Load data
trials <- read_csv(
"./data1.csv",
col_types = cols(
Participant = col_factor(),
Guide = col_factor(),
Set = col_factor(),
Phase = col_factor(),
Block = col_factor(),
Trial = col_character(),
TrialName = col_factor(),
TriggeredName = col_factor(),
Result = col_logical(),
Mode = col_factor(),
RestartCount = col_double(),
DrawTime = col_double(),
NoviceTime = col_double(),
EndTime = col_double(),
TriggerDuration = col_double(),
GripDuration = col_double(),
IdleDuration = col_double()
)
) %>%
filter(Participant != "P3" & Participant != "P6") %>%
mutate(
Participant = droplevels(Participant),
Block = factor(Block),
InputTime = EndTime-NoviceTime,
IsOutlier = Phase == "Training" &
EndTime > mean(EndTime[Phase == "Training"]) + 3 * sd(EndTime[Phase == "Training"]))
trials
# Number of outliers
a = sum(trials$IsOutlier == TRUE)
b = sum(trials$Phase == "Training")
(a/b)*100
[1] 2.314815
TIME
Trial Time
trialtime_p_summary <- trials %>%
filter(Mode == "Novice", Phase == "Training" & Result == TRUE & IsOutlier == FALSE) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(EndTime), .groups="drop")
# because P4 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P4", "Sheet", "Training", "B3", 12.201982)
trialtime_p_summary = rbind(trialtime_p_summary, newRow)
# because P11 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P11", "Sheet", "Training", "B3", 9.1895835)
# merge new row into table
trialtime_p_summary = rbind(trialtime_p_summary, newRow)
# convert from character to numbers
trialtime_p_summary$Mean <- as.numeric(as.character(trialtime_p_summary$Mean))
trialtime_p_summary
trialtime_octo <- subset(trialtime_p_summary, Guide == "Octo", Mean, drop = TRUE)
trialtime_sheet <- subset(trialtime_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(trialtime_sheet, trialtime_octo)
meandiff lwr.ci upr.ci
0.9103542 -0.3476703 2.1683788
trialtime_b1 <- subset(trialtime_p_summary, Block == "B1", Mean, drop = TRUE)
trialtime_b2 <- subset(trialtime_p_summary, Block == "B2", Mean, drop = TRUE)
trialtime_b3 <- subset(trialtime_p_summary, Block == "B3", Mean, drop = TRUE)
MeanDiffCI(trialtime_b2, trialtime_b1)
meandiff lwr.ci upr.ci
-1.6326259 -3.0862784 -0.1789734
MeanDiffCI(trialtime_b3, trialtime_b1)
meandiff lwr.ci upr.ci
-1.9928490 -3.4778429 -0.5078552
trialtime_summary <- trialtime_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
trialtime_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=trialtime_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=format(round(MeanValue,1),nsmall=1), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(trialtime_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(trialtime_summary$Guide=="Octo", -0.4, 0.4)
)+
expand_limits(y=c(0,11.5))+
labs(x="Block", y="Time (s)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(legend.background = element_blank(), legend.title = element_blank(),
legend.position = c(0.5, 0.1), legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p < 0.05. The distribution of the residuals is not normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = trialtime_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.94415, p-value = 0.008342
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
trialtime_p_summary,
dv = log(Mean),
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(trialtime_p_summary$TransVal,
trialtime_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: trialtime_p_summary$TransVal and trialtime_p_summary$Block
B1 B2
B2 0.0019 -
B3 0.0050 1.0000
P value adjustment method: bonferroni
Reaction Time
reactiontime_p_summary <- trials %>%
filter(Mode == "Novice" & Phase == "Training" & Result == TRUE & IsOutlier == FALSE) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(NoviceTime), .groups="drop")
# because P4 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P4", "Sheet", "Training", "B3", 0.93730355)
reactiontime_p_summary = rbind(reactiontime_p_summary, newRow)
# because P11 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P11", "Sheet", "Training", "B3", 1.48358335)
# merge new row into table
reactiontime_p_summary = rbind(reactiontime_p_summary, newRow)
# convert from character to numbers
reactiontime_p_summary$Mean <- as.numeric(as.character(reactiontime_p_summary$Mean))
reactiontime_p_summary
reactiontime_octo <- subset(reactiontime_p_summary, Guide == "Octo", Mean, drop = TRUE)
reactiontime_sheet <- subset(reactiontime_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(reactiontime_sheet, reactiontime_octo)
meandiff lwr.ci upr.ci
-0.8840140 -1.0874074 -0.6806207
reactiontime_summary <- reactiontime_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
reactiontime_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=reactiontime_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=format(round(MeanValue,1),nsmall=1), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(reactiontime_summary$Guide=="Octo", -0.1, 0.1),
nudge_y=ifelse(reactiontime_summary$Guide=="Octo", 0.8, -0.8)
)+
expand_limits(y=c(0,11.5))+
labs(x="Block", y="Time (s)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"))+
# facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
legend.position = "none",
# legend.position = c(0.8, 0.85), legend.direction = "vertical",
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = reactiontime_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.9734, p-value = 0.2134
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
reactiontime_p_summary,
dv = Mean,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Input Time
inputtime_p_summary <- trials %>%
filter(Mode == "Novice", Phase == "Training" & Result == TRUE & IsOutlier == FALSE) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(InputTime), .groups="drop")
# because P4 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P4", "Sheet", "Training", "B3", 11.2646785)
inputtime_p_summary = rbind(inputtime_p_summary, newRow)
# because P11 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P11", "Sheet", "Training", "B3", 7.706)
# merge new row into table
inputtime_p_summary = rbind(inputtime_p_summary, newRow)
# convert from character to numbers
inputtime_p_summary$Mean <- as.numeric(as.character(inputtime_p_summary$Mean))
inputtime_p_summary
inputtime_octo <- subset(inputtime_p_summary, Guide == "Octo", Mean, drop = TRUE)
inputtime_sheet <- subset(inputtime_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(inputtime_sheet, inputtime_octo)
meandiff lwr.ci upr.ci
1.7943683 0.5364499 3.0522866
inputtime_b1 <- subset(inputtime_p_summary, Block == "B1", Mean, drop = TRUE)
inputtime_b2 <- subset(inputtime_p_summary, Block == "B2", Mean, drop = TRUE)
inputtime_b3 <- subset(inputtime_p_summary, Block == "B3", Mean, drop = TRUE)
MeanDiffCI(inputtime_b2, inputtime_b1)
meandiff lwr.ci upr.ci
-1.52211153 -3.01745734 -0.02676572
MeanDiffCI(inputtime_b3, inputtime_b1)
meandiff lwr.ci upr.ci
-1.9165457 -3.4683654 -0.3647261
inputtime_summary <- inputtime_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
inputtime_summary
NA
Graph
pd <- position_dodge(0.4)
ggplot(data=inputtime_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=format(round(MeanValue,1),nsmall=1), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(inputtime_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(inputtime_summary$Guide=="Octo", -0.4, 0.4)
)+
expand_limits(y=c(0,11.5))+
labs(x="Block", y="Time (s)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"))+
# facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(legend.position = "none",
#legend.position = c(0.8, 0.15), legend.direction = "vertical",
# legend.background = element_blank(),
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p < 0.05. The distribution of the residuals is not normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = inputtime_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.9503, p-value = 0.01609
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
inputtime_p_summary,
dv = TransVal,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(inputtime_p_summary$TransVal,
inputtime_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: inputtime_p_summary$TransVal and inputtime_p_summary$Block
B1 B2
B2 0.0077 -
B3 0.0312 1.0000
P value adjustment method: bonferroni
ACCURACY
Overall Training
accuracy_overalltraining_p_summary <- trials %>%
filter(Phase == "Training" & !IsOutlier) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(Result), .groups="drop")
accuracy_overalltraining_p_summary
overalltrainingacc_octo <- subset(accuracy_overalltraining_p_summary, Guide == "Octo", Mean, drop = TRUE)
overalltrainingacc_sheet <- subset(accuracy_overalltraining_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(overalltrainingacc_sheet, overalltrainingacc_octo)
meandiff lwr.ci upr.ci
-0.13767985 -0.17744954 -0.09791017
accuracy_overalltraining_summary <- accuracy_overalltraining_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
accuracy_overalltraining_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=accuracy_overalltraining_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(accuracy_overalltraining_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(accuracy_overalltraining_summary$Guide=="Octo", 0.1, -0.1)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Block", y="Accuracy (%)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(legend.background = element_blank(), legend.title = element_blank(),
legend.position = c(0.5, 0.1), legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = accuracy_overalltraining_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.97962, p-value = 0.4125
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
accuracy_overalltraining_p_summary,
dv = Mean,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Expert Training
accuracy_p_expert_summary <- trials %>%
filter(Phase == "Training" & Mode == "Expert" & !IsOutlier) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(Result), .groups="drop")
accuracy_p_expert_summary
expertacc_octo <- subset(accuracy_p_expert_summary, Guide == "Octo", Mean, drop = TRUE)
expertacc_sheet <- subset(accuracy_p_expert_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(expertacc_sheet, expertacc_octo)
meandiff lwr.ci upr.ci
-0.10394979 -0.16141056 -0.04648901
expertacc_b1 <- subset(accuracy_p_expert_summary, Block == "B1", Mean, drop = TRUE)
expertacc_b2 <- subset(accuracy_p_expert_summary, Block == "B2", Mean, drop = TRUE)
expertacc_b3 <- subset(accuracy_p_expert_summary, Block == "B3", Mean, drop = TRUE)
MeanDiffCI(expertacc_b3, expertacc_b2)
meandiff lwr.ci upr.ci
-0.10574691 -0.17631257 -0.03518125
accuracy_expert_summary <- accuracy_p_expert_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
accuracy_expert_summary
Graph
ggplot(data=accuracy_expert_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(accuracy_expert_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(accuracy_expert_summary$Guide=="Octo", 0.1, -0.1)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1)) +
labs(x="Block", y="Accuracy (%)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
legend.position = "none",
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = accuracy_p_expert_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.98827, p-value = 0.8341
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
accuracy_p_expert_summary,
dv = Mean,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(accuracy_p_expert_summary$Mean,
accuracy_p_expert_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: accuracy_p_expert_summary$Mean and accuracy_p_expert_summary$Block
B1 B2
B2 0.610 -
B3 0.306 0.011
P value adjustment method: bonferroni
Novice Training
accuracy_p_novice_summary <- trials %>%
filter(Phase == "Training" & Mode == "Novice" & !IsOutlier) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(Result), .groups="drop")
# because P11 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P11", "Sheet", "Training", "B3", 0.67857145)
# merge new row into table
accuracy_p_novice_summary = rbind(accuracy_p_novice_summary, newRow)
# convert from character to numbers
accuracy_p_novice_summary$Mean <- as.numeric(as.character(accuracy_p_novice_summary$Mean))
accuracy_p_novice_summary
noviceacc_octo <- subset(accuracy_p_novice_summary, Guide == "Octo", Mean, drop = TRUE)
noviceacc_sheet <- subset(accuracy_p_novice_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(noviceacc_sheet, noviceacc_octo)
meandiff lwr.ci upr.ci
-0.2014409 -0.2824296 -0.1204522
accuracy_novice_summary <- accuracy_p_novice_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
accuracy_novice_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=accuracy_novice_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(accuracy_novice_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(accuracy_novice_summary$Guide=="Octo", 0.05, -0.05)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Block", y="Accuracy (%)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
legend.position = "none",
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = accuracy_p_novice_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.96389, p-value = 0.07298
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
accuracy_p_novice_summary,
dv = Mean,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Guess (Pre-Test)
accuracy_pretest_p_summary <- trials %>%
filter(Phase == "PreTest" & !IsOutlier) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(Result), .groups="drop")
accuracy_pretest_p_summary
accuracy_pretest_summary <- accuracy_pretest_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
pretestacc_octo <- subset(accuracy_pretest_p_summary, Guide == "Octo", Mean, drop = TRUE)
pretestacc_sheet <- subset(accuracy_pretest_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(pretestacc_sheet, pretestacc_octo)
meandiff lwr.ci upr.ci
0.005208333 -0.039921417 0.050338084
accuracy_pretest_summary
Graph
ggplot(data=accuracy_pretest_summary, aes(x=Guide, y=MeanValue, fill = Guide)) +
geom_bar(size=3,stat="identity")+
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide),
show.legend = FALSE,
size=4, nudge_y = 0.1
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Guide", y="Accuracy (%)")+
scale_x_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_fill_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
theme_bw(base_size = 12)+
theme(legend.position = "none", legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Guide + Error(Participant), data = accuracy_pretest_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.91721, p-value = 0.2637
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
accuracy_pretest_p_summary,
dv = Mean,
wid = Participant,
within = c(Guide)
)
$ANOVA
NA
Recall (Test)
accuracy_test_p_summary <- trials %>%
filter(Phase == "Test" & !IsOutlier) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(Result), .groups="drop")
accuracy_test_p_summary
maintest_octo <- subset(accuracy_test_p_summary, Guide == "Octo", Mean, drop = TRUE)
maintest_sheet <- subset(accuracy_test_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(maintest_sheet, maintest_octo)
meandiff lwr.ci upr.ci
-0.006944444 -0.114260087 0.100371198
accuracy_test_summary <- accuracy_test_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
acctest_b1 <- subset(accuracy_test_p_summary, Block == "B1", Mean, drop = TRUE)
acctest_b2 <- subset(accuracy_test_p_summary, Block == "B2", Mean, drop = TRUE)
acctest_b3 <- subset(accuracy_test_p_summary, Block == "B3", Mean, drop = TRUE)
MeanDiffCI(acctest_b2, acctest_b1)
meandiff lwr.ci upr.ci
0.20312500 0.09830948 0.30794052
MeanDiffCI(acctest_b3, acctest_b2)
meandiff lwr.ci upr.ci
0.15625000 0.05694772 0.25555228
accuracy_test_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=accuracy_test_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide),
size=4, nudge_x=ifelse(accuracy_test_summary$Guide=="Octo", -0.4, 0.4),
nudge_y=ifelse(accuracy_test_summary$Guide=="Octo", 0.1, -0.1)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Block", y="Accuracy (%)")+
scale_x_discrete(labels=c("B1-Test", "B2-Test", "B3-Test"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(legend.background = element_blank(), legend.title = element_blank(),
legend.position = c(0.5, 0.1), legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Block*Guide + Error(Participant), data = accuracy_test_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.98614, p-value = 0.7292
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
accuracy_test_p_summary,
dv = Mean,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(accuracy_test_p_summary$Mean,
accuracy_test_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: accuracy_test_p_summary$Mean and accuracy_test_p_summary$Block
B1 B2
B2 0.00016 -
B3 9.3e-08 0.00062
P value adjustment method: bonferroni
Incidental Learning (Post-test)
# excluding targets
accuracy_posttest_p_summary <- trials %>%
filter(Phase == "PostTest" & !IsOutlier) %>%
filter(TrialName != "Abu Dhabi" & TrialName != "Amsterdam" & TrialName != "Dubai" & TrialName != "Los Angeles" & TrialName != "Madrid" & TrialName != "Paris" & TrialName != "Singapore" & TrialName != "Tokyo" & TrialName != "Austin" & TrialName != "Doha" & TrialName != "Frankfurt" & TrialName != "Houston" & TrialName != "Milan" & TrialName != "Prague" & TrialName != "Seoul" & TrialName != "Toronto") %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Mean = mean(Result), .groups="drop")
accuracy_posttest_p_summary
accuracyposttest_octo <- subset(accuracy_posttest_p_summary, Guide == "Octo", Mean, drop = TRUE)
accuracyposttest_sheet <- subset(accuracy_posttest_p_summary, Guide == "Sheet", Mean, drop = TRUE)
MeanDiffCI(accuracyposttest_octo, accuracyposttest_sheet)
meandiff lwr.ci upr.ci
-0.06250000 -0.21695935 0.09195935
accuracy_posttest_summary <- accuracy_posttest_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
accuracy_posttest_summary
Graph
ggplot(data=accuracy_posttest_summary, aes(x=Guide, y=MeanValue, fill = Guide)) +
geom_bar(size=3,stat="identity")+
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide),
show.legend = FALSE,
size=4, nudge_y = 0.05, nudge_x = 0.3
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Guide", y="Accuracy (%)")+
scale_x_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_fill_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
theme_bw(base_size = 12)+
theme(legend.position = "none", legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ Guide + Error(Participant), data = accuracy_posttest_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.97556, p-value = 0.9595
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
accuracy_posttest_p_summary,
dv = Mean,
wid = Participant,
within = c(Guide)
)
$ANOVA
NA
Learning Curve (combined, only 8 trained gestures)
targets <- c("Abu Dhabi", "Amsterdam", "Dubai", "Los Angeles", "Madrid", "Paris", "Singapore", "Tokyo", "Austin", "Doha", "Frankfurt", "Houston", "Milan", "Prague", "Seoul", "Toronto")
curve_p_summary <- trials %>%
filter(TrialName %in% targets & Phase!="Training" & !IsOutlier) %>%
mutate(PhaseName = ifelse(Phase=="Test" & Block=="B1", "Test B1",
ifelse(Phase=="Test" & Block=="B2", "Test B2",
ifelse(Phase=="Test" & Block=="B3", "Test B3",
ifelse(Phase=="PreTest", "PreTest",
ifelse(Phase=="PostTest", "PostTest",NA)))))) %>%
mutate(PhaseName = fct_relevel(PhaseName,
"PreTest", "Test B1", "Test B2", "Test B3", "PostTest")) %>%
mutate(PhaseName = as.factor(PhaseName)) %>%
group_by(Participant, Guide, PhaseName) %>%
summarize(Mean = mean(Result), .groups="drop")
curve_p_summary
curve_summary <- curve_p_summary %>%
group_by(Guide, PhaseName) %>%
summarize(summary_with_ci(Mean), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
curve_summary
curve_testB3 <- subset(curve_p_summary, PhaseName == "Test B3", Mean, drop = TRUE)
curve_posttest <- subset(curve_p_summary, PhaseName == "PostTest", Mean, drop = TRUE)
MeanDiffCI(curve_posttest, curve_testB3)
meandiff lwr.ci upr.ci
-0.088541667 -0.180952498 0.003869164
Graph
pd <- position_dodge(0.4)
ggplot(data=curve_summary, aes(x=PhaseName, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide),
size=4, nudge_x=ifelse(curve_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(curve_summary$Guide=="Octo", 0.1, -0.1),
show.legend = FALSE
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Phase", y="Accuracy (%)")+
# scale_x_discrete(labels=c("B1-Test", "B2-Test", "B3-Test"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(legend.background = element_blank(), legend.title = element_blank(),
legend.position = c(0.5, 0.1), legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(Mean ~ PhaseName*Guide + Error(Participant), data = curve_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.98288, p-value = 0.1804
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
# curve_p_summary_new = filter(curve_p_summary, PhaseName=="Test B3" | PhaseName=="PostTest")
# curve_p_summary_new
ezANOVA(
curve_p_summary,
dv = Mean,
wid = Participant,
within = c(Guide, PhaseName)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(curve_p_summary$Mean,
curve_p_summary$PhaseName,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: curve_p_summary$Mean and curve_p_summary$PhaseName
PreTest Test B1 Test B2 Test B3
Test B1 1.5e-07 - - -
Test B2 2.9e-11 0.00054 - -
Test B3 1.2e-13 3.1e-07 0.00206 -
PostTest 2.8e-14 3.1e-06 1.00000 0.06527
P value adjustment method: bonferroni
OTHERS
Expert Mode Rate (during Training)
expertproportion_p_summary <- trials %>%
filter(Phase == "Training" & !IsOutlier) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(ExpertCount = sum(Mode=="Expert"),
Total = sum(Mode=="Novice") + sum(Mode=="Expert"),
ExpertPercent = (sum(Mode=="Expert")/Total),
.groups="drop")
expertproportion_p_summary
expertpro_octo <- subset(expertproportion_p_summary, Guide == "Octo", ExpertPercent, drop = TRUE)
expertpro_sheet <- subset(expertproportion_p_summary, Guide == "Sheet", ExpertPercent, drop = TRUE)
MeanDiffCI(expertpro_sheet, expertpro_octo)
meandiff lwr.ci upr.ci
0.08249224 -0.01075320 0.17573767
expertpro_b1 <- subset(expertproportion_p_summary, Block == "B1", ExpertPercent, drop = TRUE)
expertpro_b2 <- subset(expertproportion_p_summary, Block == "B2", ExpertPercent, drop = TRUE)
expertpro_b3 <- subset(expertproportion_p_summary, Block == "B3", ExpertPercent, drop = TRUE)
MeanDiffCI(expertpro_b2, expertpro_b1)
meandiff lwr.ci upr.ci
0.13864872 0.04034435 0.23695309
MeanDiffCI(expertpro_b3, expertpro_b1)
meandiff lwr.ci upr.ci
0.20440037 0.09425377 0.31454697
expertproportion_summary <- expertproportion_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(ExpertPercent), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
expertproportion_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=expertproportion_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide),
size=4, nudge_x=ifelse(expertproportion_summary$Guide=="Octo", -0.35, 0.35),
nudge_y=ifelse(expertproportion_summary$Guide=="Octo", -0.15, 0.15)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Block", y="Usage Rate (%)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"),labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_shape_discrete(labels=c("OCTOPOCUS","CRIBSHEET"))+
scale_linetype(labels=c("OCTOPOCUS","CRIBSHEET"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(legend.background = element_blank(), legend.title = element_blank(),
legend.position = c(0.5, 0.1), legend.direction = "horizontal",
panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(ExpertPercent ~ Block*Guide + Error(Participant), data = expertproportion_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.96087, p-value = 0.05191
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
expertproportion_p_summary,
dv = ExpertPercent,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(expertproportion_p_summary$ExpertPercent,
expertproportion_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: expertproportion_p_summary$ExpertPercent and expertproportion_p_summary$Block
B1 B2
B2 0.00012 -
B3 0.00081 0.25270
P value adjustment method: bonferroni
Exploration Mode Rate (during Training)
exploreprop_p_summary <- trials %>%
filter(Phase == "Training" & !IsOutlier) %>%
mutate(isExploring = ifelse(GripDuration>0, 1, 0)) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Frequency = sum(isExploring),
Total = sum(Mode=="Novice") + sum(Mode=="Expert"),
Proportion = (Frequency/Total),
.groups="drop")
exploreprop_p_summary
exploreprop_summary <- exploreprop_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(Proportion), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
exploreprop_summary
explorepro_octo <- subset(exploreprop_p_summary, Guide == "Octo", Proportion, drop = TRUE)
explorepro_sheet <- subset(exploreprop_p_summary, Guide == "Sheet", Proportion, drop = TRUE)
MeanDiffCI(explorepro_sheet, explorepro_octo)
meandiff lwr.ci upr.ci
0.2374574 0.1710811 0.3038337
explorepro_b1 <- subset(exploreprop_p_summary, Block == "B1", Proportion, drop = TRUE)
explorepro_b2 <- subset(exploreprop_p_summary, Block == "B2", Proportion, drop = TRUE)
explorepro_b3 <- subset(exploreprop_p_summary, Block == "B3", Proportion, drop = TRUE)
MeanDiffCI(explorepro_b2, explorepro_b1)
meandiff lwr.ci upr.ci
-0.14020445 -0.23863576 -0.04177314
MeanDiffCI(explorepro_b3, explorepro_b2)
meandiff lwr.ci upr.ci
-0.07844066 -0.17151924 0.01463792
Graph
pd <- position_dodge(0.4)
ggplot(data=exploreprop_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(exploreprop_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(exploreprop_summary$Guide=="Octo", -0.05, 0.05)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Block", y="Usage Rate (%)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
legend.position = "none",
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p < 0.05. The distribution of the residuals is not normal.
m = aov(Proportion ~ Block*Guide + Error(Participant), data = exploreprop_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.94881, p-value = 0.01369
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
exploreprop_p_summary,
dv = TransVal,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(exploreprop_p_summary$TransVal,
exploreprop_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: exploreprop_p_summary$TransVal and exploreprop_p_summary$Block
B1 B2
B2 1.6e-05 -
B3 1.2e-07 0.012
P value adjustment method: bonferroni
OCTO Exploration Mode Rate (during Training)
exploreprop_octo_p_summary <- trials %>%
filter(Guide == "Octo" & Phase == "Training" & !IsOutlier) %>%
mutate(isExploring = ifelse(GripDuration>0, 1, 0)) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(Frequency = sum(isExploring),
Total = sum(Mode=="Novice") + sum(Mode=="Expert"),
Proportion = (Frequency/Total),
.groups="drop")
exploreprop_octo_p_summary
exploreprop_octo_summary <- exploreprop_octo_p_summary %>%
group_by(Guide,Block) %>%
summarize(summary_with_ci(Proportion), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
exploreprop_octo_summary
explorepro_octo_b1 <- subset(exploreprop_octo_p_summary, Block == "B1", Proportion, drop = TRUE)
explorepro_octo_b2 <- subset(exploreprop_octo_p_summary, Block == "B2", Proportion, drop = TRUE)
explorepro_octo_b3 <- subset(exploreprop_octo_p_summary, Block == "B3", Proportion, drop = TRUE)
MeanDiffCI(explorepro_octo_b2, explorepro_octo_b1)
meandiff lwr.ci upr.ci
-0.14131415 -0.20145971 -0.08116859
MeanDiffCI(explorepro_octo_b3, explorepro_octo_b1)
meandiff lwr.ci upr.ci
-0.1785616 -0.2336920 -0.1234312
Graph
pd <- position_dodge(0.4)
ggplot(data=exploreprop_octo_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=sprintf("%.0f", 100*MeanValue), color=Guide), show.legend = FALSE,
size=4, nudge_x=ifelse(exploreprop_octo_summary$Guide=="Octo", -0.3, 0.3),
nudge_y=ifelse(exploreprop_octo_summary$Guide=="Octo", -0.05, 0.05)
)+
scale_y_continuous(labels = function(x) paste0(x*100),breaks = seq(0,1,0.25))+
# scale_y_continuous(labels = label_percent(), breaks = seq(0,1,0.25))+
expand_limits(y=c(0,1))+
labs(x="Block", y="Usage Rate (%)")+
scale_x_discrete(labels=c("B1-Train", "B2-Train", "B3-Train"))+
scale_color_manual(values = c("#d35400", "#95a5a6"))+
facet_grid(scales = "free", space = "free")+
theme_bw(base_size = 12)+
theme(panel.border = element_blank(),
axis.line = element_line(color = 'grey'),
legend.position = "none",
axis.text.x = element_text(size = 12), axis.text.y = element_text(size = 12),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p < 0.05. The distribution of the residuals is not normal.
m = aov(Proportion ~ Block + Error(Participant), data = exploreprop_octo_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.90988, p-value = 0.03505
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
exploreprop_octo_p_summary,
dv = TransVal,
wid = Participant,
within = c(Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(exploreprop_octo_p_summary$TransVal,
exploreprop_octo_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: exploreprop_octo_p_summary$TransVal and exploreprop_octo_p_summary$Block
B1 B2
B2 0.00168 -
B3 0.00015 0.36135
P value adjustment method: bonferroni
Explore Duration
modedtime_p_summary <- trials %>%
filter(Mode == "Novice", Phase == "Training" & Result == TRUE & IsOutlier == FALSE) %>%
group_by(Participant, Guide, Phase, Block) %>%
summarize(MeanIdle = mean(IdleDuration), MeanGrip = mean(GripDuration), MeanTrigger = mean(TriggerDuration), .groups="drop")
# because P4 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P4", "Sheet", "Training", "B3", 2.5109465, 7.72282145, 1.968268)
modedtime_p_summary = rbind(modedtime_p_summary, newRow)
# because P11 has zero novice trial in B3, we averaged values between that of B1 and B2
newRow = c("P11", "Sheet", "Training", "B3", 3.3913335, 4.0635, 1.73475)
# merge new row into table
modedtime_p_summary = rbind(modedtime_p_summary, newRow)
# # convert from character to numbers
modedtime_p_summary$MeanIdle <- as.numeric(as.character(modedtime_p_summary$MeanIdle))
modedtime_p_summary$MeanGrip <- as.numeric(as.character(modedtime_p_summary$MeanGrip))
modedtime_p_summary$MeanTrigger <- as.numeric(as.character(modedtime_p_summary$MeanTrigger))
modedtime_p_summary
idletime_summary <- modedtime_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(MeanIdle), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
idletime_summary
griptime_summary <- modedtime_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(MeanGrip), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
griptime_summary
triggertime_summary <- modedtime_p_summary %>%
group_by(Guide, Phase, Block) %>%
summarize(summary_with_ci(MeanTrigger), .groups="drop") %>%
mutate(LowerValue = if_else(LowerValue < 0, 0, LowerValue))
triggertime_summary
Graph
pd <- position_dodge(0.4)
ggplot(data=griptime_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(linetype=Guide, color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=format(round(MeanValue,3),nsmall=3), color=Guide),
size=4, nudge_x=ifelse(griptime_summary$Guide=="Octo", -0.35, 0.35),
nudge_y=ifelse(griptime_summary$Guide=="Octo", -0.4, 0.4)
)+
expand_limits(y=c(0,6))+
labs(x="Block", y="Explore Duration (s)")+
facet_grid(~Phase, scales = "free", space = "free")+
theme(legend.position = "none",
#legend.position = c(0.85, 0.85), legend.direction = "vertical",
axis.text.x = element_text(size = 10), axis.text.y = element_text(size = 10),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p < 0.05. The distribution of the residuals is not normal.
m = aov(MeanGrip ~ Block*Guide + Error(Participant), data = modedtime_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.9576, p-value = 0.03595
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
modedtime_p_summary,
dv = sqrt(MeanGrip),
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
Pairwise Comparison
pairwise.t.test(sqrt(modedtime_p_summary$MeanGrip),
modedtime_p_summary$Block,
paired=TRUE,
p.adj="bonf")
Pairwise comparisons using paired t tests
data: sqrt(modedtime_p_summary$MeanGrip) and modedtime_p_summary$Block
B1 B2
B2 0.0046 -
B3 0.0807 1.0000
P value adjustment method: bonferroni
Draw Duration
Graph
pd <- position_dodge(0.4)
ggplot(data=triggertime_summary, aes(x=Block, y=MeanValue, group=Guide)) +
geom_errorbar(aes(ymin=LowerValue, ymax=UpperValue), width=.3, position=pd) +
geom_line(aes(linetype=Guide, color=Guide), position=pd)+
geom_point(aes(color=Guide, shape=Guide), size=3, position=pd)+
geom_text(aes(label=format(round(MeanValue,3),nsmall=3), color=Guide),
size=4, nudge_x=ifelse(triggertime_summary$Guide=="Octo", -0.35, 0.35),
nudge_y=ifelse(triggertime_summary$Guide=="Octo", -0.4, 0.4)
)+
expand_limits(y=c(0,6))+
labs(x="Block", y="Draw Duration (s)")+
facet_grid(~Phase, scales = "free", space = "free")+
theme(legend.position = c(0.85, 0.15), legend.direction = "vertical",
axis.text.x = element_text(size = 10), axis.text.y = element_text(size = 10),
axis.title.y = element_text(margin = margin(t = 0, r = 5, b = 0, l = 0)),
axis.title.x = element_text(margin = margin(t = 5, r = 0, b = 0, l = 0)))

Assumptions
Shapiro test p > 0.05. The distribution of the residuals is normal.
m = aov(MeanTrigger ~ Block*Guide + Error(Participant), data = modedtime_p_summary)
shapiro.test(residuals(m$Within))
Shapiro-Wilk normality test
data: residuals(m$Within)
W = 0.97384, p-value = 0.2239
plotNormalHistogram(residuals(m$Within))

qqnorm(residuals(m$Within)); qqline(residuals(m$Within))

ANOVA
ezANOVA(
modedtime_p_summary,
dv = MeanTrigger,
wid = Participant,
within = c(Guide, Block)
)
$ANOVA
$`Mauchly's Test for Sphericity`
$`Sphericity Corrections`
NA
SUBJECTIVE RATING
ratingParticipant <- read_csv("./data2.csv")
Parsed with column specification:
cols(
Participant = [31mcol_character()[39m,
Gender = [31mcol_character()[39m,
Age = [32mcol_double()[39m,
Guide = [31mcol_character()[39m,
Easy = [32mcol_double()[39m,
Fast = [32mcol_double()[39m,
Accurate = [32mcol_double()[39m,
Comfortable = [32mcol_double()[39m,
RememberMany = [32mcol_double()[39m
)
ratingCount <- read_csv("./data3.csv")
Parsed with column specification:
cols(
Question = [31mcol_character()[39m,
Guide = [31mcol_character()[39m,
`Strongly Disagree` = [32mcol_double()[39m,
Disagree = [32mcol_double()[39m,
`Slightly Disagree` = [32mcol_double()[39m,
Neutral = [32mcol_double()[39m,
`Slightly Agree` = [32mcol_double()[39m,
Agree = [32mcol_double()[39m,
`Strongly Agree` = [32mcol_double()[39m
)
overall <- read_csv("./data4.csv")
Parsed with column specification:
cols(
Participant = [31mcol_character()[39m,
Gender = [31mcol_character()[39m,
Age = [32mcol_double()[39m,
Overall = [31mcol_character()[39m,
Frequency = [31mcol_character()[39m
)
length(unique(overall$Participant))
[1] 12
ratingParticipant
names(ratingCount)[3] <- "Strongly\nDisagree"
names(ratingCount)[5] <- "Slightly\nDisagree"
names(ratingCount)[7] <- "Slightly\nAgree"
names(ratingCount)[9] <- "Strongly\nAgree"
ratingCount
likert(Question ~ .| Guide, data=ratingCount, layout=c(1,2),
scales=list(y=list(relation="free")),between=list(y=2.5),
strip.left=FALSE, strip=FALSE,
par.strip.text=list(cex=1, lines=2), ylab=NULL, cex=1.2,
xlim=c(-100,-50, -25, 0, 25, 50, 75, 100),
ReferenceZero=4, as.percent="noRightAxis",
reference.line.col="black",
col=c("#D31819", "#FF792E", "#FFAE73", "#DED9D9", "#74AED5", "#3881B8", "#0E529F"),
borders = list(),
positive.order=FALSE,
main = list(""),
xlab="Proportion (%)",
auto.key=list(space="bottom", rows=1, reverse=FALSE, padding.text=1,
rect= list(col=c("#D31819", "#FF792E", "#FFAE73", "#DED9D9", "#74AED5", "#3881B8", "#0E529F"), # <- Specify colors again (for keys)
border = "black")))

# export to pdf: 4.0 x 8.5 inch
ratingParticipantLong = pivot_longer(ratingParticipant, cols = 5:9, names_to = "Question", values_to = "Rating")
ratingParticipantLong
wilcox <- ratingParticipantLong %>%
group_by(Question) %>%
wilcox_test(Rating ~ Guide, paired=TRUE) %>%
add_significance("p")
wilcox
LS0tCnRpdGxlOiAiT2N0b1BvY3VzIGluIFZSIC0gUmVzdWx0IEFuYWx5c2lzIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0aGVtZTogbHVtZW4KICAgIGhpZ2hsaWdodDogZGVmYXVsdAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBudW1iZXJfc2VjdGlvbnM6IFRSVUUKLS0tCgojIFRvb2xzICYgTGlicmFyaWVzCgpgYGB7cn0KbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoZXopCmxpYnJhcnkoTUFTUykKbGlicmFyeShlZmZzaXplKQpsaWJyYXJ5KHJjb21wYW5pb24pCmxpYnJhcnkoQVJUb29sKQpsaWJyYXJ5KGVtbWVhbnMpCmxpYnJhcnkoSEgpCmxpYnJhcnkocnN0YXRpeCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoRGVzY1Rvb2xzKQoKCm5vcm1hbF9lcnJvciA8LSBmdW5jdGlvbihkKSB7CiAgbiA8LSBsZW5ndGgoZCkKICBxbm9ybSgwLjk3NSkgKiAoc2QoZCkgL3NxcnQobikpCn0KCnN1bW1hcnlfd2l0aF9jaSA8LSBmdW5jdGlvbihkKSB7CiAgdGliYmxlKAogICAgTWVhblZhbHVlID0gbWVhbihkKSwKICAgIEVycm9yVmFsdWUgPSBub3JtYWxfZXJyb3IoZCksCiAgICBMb3dlclZhbHVlID0gTWVhblZhbHVlIC0gRXJyb3JWYWx1ZSwKICAgIFVwcGVyVmFsdWUgPSBNZWFuVmFsdWUgKyBFcnJvclZhbHVlCiAgKQp9CmBgYAojIExvYWQgZGF0YQoKYGBge3J9CnRyaWFscyA8LSByZWFkX2NzdigKICAiLi9kYXRhMS5jc3YiLAogIGNvbF90eXBlcyA9IGNvbHMoCiAgICBQYXJ0aWNpcGFudCA9IGNvbF9mYWN0b3IoKSwKICAgIEd1aWRlID0gY29sX2ZhY3RvcigpLAogICAgU2V0ID0gY29sX2ZhY3RvcigpLAogICAgUGhhc2UgPSBjb2xfZmFjdG9yKCksCiAgICBCbG9jayA9IGNvbF9mYWN0b3IoKSwKICAgIFRyaWFsID0gY29sX2NoYXJhY3RlcigpLAogICAgVHJpYWxOYW1lID0gY29sX2ZhY3RvcigpLAogICAgVHJpZ2dlcmVkTmFtZSA9IGNvbF9mYWN0b3IoKSwKICAgIFJlc3VsdCA9IGNvbF9sb2dpY2FsKCksCiAgICBNb2RlID0gY29sX2ZhY3RvcigpLAogICAgUmVzdGFydENvdW50ID0gY29sX2RvdWJsZSgpLAogICAgRHJhd1RpbWUgPSBjb2xfZG91YmxlKCksCiAgICBOb3ZpY2VUaW1lID0gY29sX2RvdWJsZSgpLAogICAgRW5kVGltZSA9IGNvbF9kb3VibGUoKSwKICAgIFRyaWdnZXJEdXJhdGlvbiA9IGNvbF9kb3VibGUoKSwKICAgIEdyaXBEdXJhdGlvbiA9IGNvbF9kb3VibGUoKSwKICAgIElkbGVEdXJhdGlvbiA9IGNvbF9kb3VibGUoKQogICkKKSAlPiUKICBmaWx0ZXIoUGFydGljaXBhbnQgIT0gIlAzIiAmIFBhcnRpY2lwYW50ICE9ICJQNiIpICU+JQogIG11dGF0ZSgKICAgIFBhcnRpY2lwYW50ID0gZHJvcGxldmVscyhQYXJ0aWNpcGFudCksCiAgICBCbG9jayA9IGZhY3RvcihCbG9jayksCiAgICBJbnB1dFRpbWUgPSBFbmRUaW1lLU5vdmljZVRpbWUsCiAgICBJc091dGxpZXIgPSBQaGFzZSA9PSAiVHJhaW5pbmciICYKICAgICAgICAgICBFbmRUaW1lID4gbWVhbihFbmRUaW1lW1BoYXNlID09ICJUcmFpbmluZyJdKSArIDMgKiBzZChFbmRUaW1lW1BoYXNlID09ICJUcmFpbmluZyJdKSkKCnRyaWFscwoKIyBOdW1iZXIgb2Ygb3V0bGllcnMKYSA9IHN1bSh0cmlhbHMkSXNPdXRsaWVyID09IFRSVUUpCmIgPSBzdW0odHJpYWxzJFBoYXNlID09ICJUcmFpbmluZyIpCihhL2IpKjEwMAoKYGBgCgojIFRJTUUKCiMjIFRyaWFsIFRpbWUKYGBge3J9CnRyaWFsdGltZV9wX3N1bW1hcnkgPC0gdHJpYWxzICU+JQogIGZpbHRlcihNb2RlID09ICJOb3ZpY2UiLCBQaGFzZSA9PSAiVHJhaW5pbmciICYgUmVzdWx0ID09IFRSVUUgJiBJc091dGxpZXIgPT0gRkFMU0UpICU+JQogIGdyb3VwX2J5KFBhcnRpY2lwYW50LCBHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoTWVhbiA9IG1lYW4oRW5kVGltZSksIC5ncm91cHM9ImRyb3AiKQoKIyBiZWNhdXNlIFA0IGhhcyB6ZXJvIG5vdmljZSB0cmlhbCBpbiBCMywgd2UgYXZlcmFnZWQgdmFsdWVzIGJldHdlZW4gdGhhdCBvZiBCMSBhbmQgQjIKbmV3Um93ID0gYygiUDQiLCAiU2hlZXQiLCAiVHJhaW5pbmciLCAiQjMiLCAxMi4yMDE5ODIpCnRyaWFsdGltZV9wX3N1bW1hcnkgPSByYmluZCh0cmlhbHRpbWVfcF9zdW1tYXJ5LCBuZXdSb3cpCiMgYmVjYXVzZSBQMTEgaGFzIHplcm8gbm92aWNlIHRyaWFsIGluIEIzLCB3ZSBhdmVyYWdlZCB2YWx1ZXMgYmV0d2VlbiB0aGF0IG9mIEIxIGFuZCBCMgpuZXdSb3cgPSBjKCJQMTEiLCAiU2hlZXQiLCAiVHJhaW5pbmciLCAiQjMiLCA5LjE4OTU4MzUpCiMgbWVyZ2UgbmV3IHJvdyBpbnRvIHRhYmxlCnRyaWFsdGltZV9wX3N1bW1hcnkgPSByYmluZCh0cmlhbHRpbWVfcF9zdW1tYXJ5LCBuZXdSb3cpCiMgY29udmVydCBmcm9tIGNoYXJhY3RlciB0byBudW1iZXJzCnRyaWFsdGltZV9wX3N1bW1hcnkkTWVhbiA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih0cmlhbHRpbWVfcF9zdW1tYXJ5JE1lYW4pKQp0cmlhbHRpbWVfcF9zdW1tYXJ5Cgp0cmlhbHRpbWVfb2N0byA8LSBzdWJzZXQodHJpYWx0aW1lX3Bfc3VtbWFyeSwgIEd1aWRlID09ICJPY3RvIiwgTWVhbiwgZHJvcCA9IFRSVUUpCnRyaWFsdGltZV9zaGVldCA8LSBzdWJzZXQodHJpYWx0aW1lX3Bfc3VtbWFyeSwgIEd1aWRlID09ICJTaGVldCIsIE1lYW4sIGRyb3AgPSBUUlVFKQpNZWFuRGlmZkNJKHRyaWFsdGltZV9zaGVldCwgdHJpYWx0aW1lX29jdG8pCgp0cmlhbHRpbWVfYjEgPC0gc3Vic2V0KHRyaWFsdGltZV9wX3N1bW1hcnksICBCbG9jayA9PSAiQjEiLCBNZWFuLCBkcm9wID0gVFJVRSkKdHJpYWx0aW1lX2IyIDwtIHN1YnNldCh0cmlhbHRpbWVfcF9zdW1tYXJ5LCAgQmxvY2sgPT0gIkIyIiwgTWVhbiwgZHJvcCA9IFRSVUUpCnRyaWFsdGltZV9iMyA8LSBzdWJzZXQodHJpYWx0aW1lX3Bfc3VtbWFyeSwgIEJsb2NrID09ICJCMyIsIE1lYW4sIGRyb3AgPSBUUlVFKQpNZWFuRGlmZkNJKHRyaWFsdGltZV9iMiwgdHJpYWx0aW1lX2IxKQpNZWFuRGlmZkNJKHRyaWFsdGltZV9iMywgdHJpYWx0aW1lX2IxKQoKdHJpYWx0aW1lX3N1bW1hcnkgPC0gdHJpYWx0aW1lX3Bfc3VtbWFyeSAlPiUKICBncm91cF9ieShHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoc3VtbWFyeV93aXRoX2NpKE1lYW4pLCAuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKExvd2VyVmFsdWUgPSBpZl9lbHNlKExvd2VyVmFsdWUgPCAwLCAwLCBMb3dlclZhbHVlKSkKdHJpYWx0aW1lX3N1bW1hcnkKYGBgCgojIyMgR3JhcGgKCmBgYHtyfQpwZCA8LSBwb3NpdGlvbl9kb2RnZSgwLjQpCgpnZ3Bsb3QoZGF0YT10cmlhbHRpbWVfc3VtbWFyeSwgYWVzKHg9QmxvY2ssIHk9TWVhblZhbHVlLCBncm91cD1HdWlkZSkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUxvd2VyVmFsdWUsIHltYXg9VXBwZXJWYWx1ZSksIHdpZHRoPS4zLCBwb3NpdGlvbj1wZCkgKwogIGdlb21fbGluZShhZXMoY29sb3I9R3VpZGUpLCBwb3NpdGlvbj1wZCkrCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9R3VpZGUsIHNoYXBlPUd1aWRlKSwgc2l6ZT0zLCBwb3NpdGlvbj1wZCkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1mb3JtYXQocm91bmQoTWVhblZhbHVlLDEpLG5zbWFsbD0xKSwgY29sb3I9R3VpZGUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgICBzaXplPTQsIG51ZGdlX3g9aWZlbHNlKHRyaWFsdGltZV9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjMsIDAuMyksCiAgICAgICAgICAgIG51ZGdlX3k9aWZlbHNlKHRyaWFsdGltZV9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjQsIDAuNCkKICApKwogIGV4cGFuZF9saW1pdHMoeT1jKDAsMTEuNSkpKwogIGxhYnMoeD0iQmxvY2siLCB5PSJUaW1lIChzKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkIxLVRyYWluIiwgIkIyLVRyYWluIiwgIkIzLVRyYWluIikpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjZDM1NDAwIiwgIiM5NWE1YTYiKSxsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX3NoYXBlX2Rpc2NyZXRlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgc2NhbGVfbGluZXR5cGUobGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBmYWNldF9ncmlkKHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZSIpKwogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSsKICB0aGVtZShsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC41LCAwLjEpLCBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMCwgciA9IDUsIGIgPSAwLCBsID0gMCkpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAwLCBiID0gMCwgbCA9IDApKSkKYGBgCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPCAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm90IG5vcm1hbC4KCmBgYHtyfQptID0gYW92KE1lYW4gfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IHRyaWFsdGltZV9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAoKIyMjIERhdGEgVHJhbnNmb3JtYXRpb24KU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm93IG5vcm1hbC4KCmBgYHtyfQp0cmlhbHRpbWVfcF9zdW1tYXJ5JFRyYW5zVmFsID0gbG9nKHRyaWFsdGltZV9wX3N1bW1hcnkkTWVhbikKbSA9IGFvdihUcmFuc1ZhbCB+IEJsb2NrKkd1aWRlICsgRXJyb3IoUGFydGljaXBhbnQpLCBkYXRhID0gdHJpYWx0aW1lX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKCmBgYHtyfQplekFOT1ZBKAogIHRyaWFsdGltZV9wX3N1bW1hcnksCiAgZHYgPSBsb2coTWVhbiksCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KHRyaWFsdGltZV9wX3N1bW1hcnkkVHJhbnNWYWwsIAogICAgICAgICAgICAgICAgdHJpYWx0aW1lX3Bfc3VtbWFyeSRCbG9jaywgCiAgICAgICAgICAgICAgICBwYWlyZWQ9VFJVRSwgCiAgICAgICAgICAgICAgICBwLmFkaj0iYm9uZiIpCmBgYAoKIyMgUmVhY3Rpb24gVGltZQpgYGB7cn0KcmVhY3Rpb250aW1lX3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKE1vZGUgPT0gIk5vdmljZSIgJiBQaGFzZSA9PSAiVHJhaW5pbmciICYgUmVzdWx0ID09IFRSVUUgJiBJc091dGxpZXIgPT0gRkFMU0UpICU+JQogIGdyb3VwX2J5KFBhcnRpY2lwYW50LCBHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoTWVhbiA9IG1lYW4oTm92aWNlVGltZSksIC5ncm91cHM9ImRyb3AiKQoKIyBiZWNhdXNlIFA0IGhhcyB6ZXJvIG5vdmljZSB0cmlhbCBpbiBCMywgd2UgYXZlcmFnZWQgdmFsdWVzIGJldHdlZW4gdGhhdCBvZiBCMSBhbmQgQjIKbmV3Um93ID0gYygiUDQiLCAiU2hlZXQiLCAiVHJhaW5pbmciLCAiQjMiLCAwLjkzNzMwMzU1KQpyZWFjdGlvbnRpbWVfcF9zdW1tYXJ5ID0gcmJpbmQocmVhY3Rpb250aW1lX3Bfc3VtbWFyeSwgbmV3Um93KQojIGJlY2F1c2UgUDExIGhhcyB6ZXJvIG5vdmljZSB0cmlhbCBpbiBCMywgd2UgYXZlcmFnZWQgdmFsdWVzIGJldHdlZW4gdGhhdCBvZiBCMSBhbmQgQjIKbmV3Um93ID0gYygiUDExIiwgIlNoZWV0IiwgIlRyYWluaW5nIiwgIkIzIiwgMS40ODM1ODMzNSkKIyBtZXJnZSBuZXcgcm93IGludG8gdGFibGUKcmVhY3Rpb250aW1lX3Bfc3VtbWFyeSA9IHJiaW5kKHJlYWN0aW9udGltZV9wX3N1bW1hcnksIG5ld1JvdykKIyBjb252ZXJ0IGZyb20gY2hhcmFjdGVyIHRvIG51bWJlcnMKcmVhY3Rpb250aW1lX3Bfc3VtbWFyeSRNZWFuIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHJlYWN0aW9udGltZV9wX3N1bW1hcnkkTWVhbikpCnJlYWN0aW9udGltZV9wX3N1bW1hcnkKCnJlYWN0aW9udGltZV9vY3RvIDwtIHN1YnNldChyZWFjdGlvbnRpbWVfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIk9jdG8iLCBNZWFuLCBkcm9wID0gVFJVRSkKcmVhY3Rpb250aW1lX3NoZWV0IDwtIHN1YnNldChyZWFjdGlvbnRpbWVfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIlNoZWV0IiwgTWVhbiwgZHJvcCA9IFRSVUUpCk1lYW5EaWZmQ0kocmVhY3Rpb250aW1lX3NoZWV0LCByZWFjdGlvbnRpbWVfb2N0bykKCnJlYWN0aW9udGltZV9zdW1tYXJ5IDwtIHJlYWN0aW9udGltZV9wX3N1bW1hcnkgJT4lCiAgZ3JvdXBfYnkoR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKHN1bW1hcnlfd2l0aF9jaShNZWFuKSwgLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShMb3dlclZhbHVlID0gaWZfZWxzZShMb3dlclZhbHVlIDwgMCwgMCwgTG93ZXJWYWx1ZSkpCnJlYWN0aW9udGltZV9zdW1tYXJ5CmBgYAoKIyMjIEdyYXBoCgpgYGB7cn0KcGQgPC0gcG9zaXRpb25fZG9kZ2UoMC40KQoKZ2dwbG90KGRhdGE9cmVhY3Rpb250aW1lX3N1bW1hcnksIGFlcyh4PUJsb2NrLCB5PU1lYW5WYWx1ZSwgZ3JvdXA9R3VpZGUpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1Mb3dlclZhbHVlLCB5bWF4PVVwcGVyVmFsdWUpLCB3aWR0aD0uMywgcG9zaXRpb249cGQpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPUd1aWRlKSwgcG9zaXRpb249cGQpKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPUd1aWRlLCBzaGFwZT1HdWlkZSksIHNpemU9MywgcG9zaXRpb249cGQpKwogIGdlb21fdGV4dChhZXMobGFiZWw9Zm9ybWF0KHJvdW5kKE1lYW5WYWx1ZSwxKSxuc21hbGw9MSksIGNvbG9yPUd1aWRlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSwKICAgICAgICAgICAgc2l6ZT00LCBudWRnZV94PWlmZWxzZShyZWFjdGlvbnRpbWVfc3VtbWFyeSRHdWlkZT09Ik9jdG8iLCAtMC4xLCAwLjEpLAogICAgICAgICAgICBudWRnZV95PWlmZWxzZShyZWFjdGlvbnRpbWVfc3VtbWFyeSRHdWlkZT09Ik9jdG8iLCAwLjgsIC0wLjgpCiAgKSsKICBleHBhbmRfbGltaXRzKHk9YygwLDExLjUpKSsKICBsYWJzKHg9IkJsb2NrIiwgeT0iVGltZSAocykiKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJCMS1UcmFpbiIsICJCMi1UcmFpbiIsICJCMy1UcmFpbiIpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IikpKwogICMgZmFjZXRfZ3JpZChzY2FsZXMgPSAiZnJlZSIsIHNwYWNlID0gImZyZWUiKSsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAxMikrCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICdncmV5JyksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgICMgbGVnZW5kLnBvc2l0aW9uID0gYygwLjgsIDAuODUpLCBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAsIHIgPSA1LCBiID0gMCwgbCA9IDApKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMCwgYiA9IDAsIGwgPSAwKSkpCmBgYAoKIyMjIEFzc3VtcHRpb25zClNoYXBpcm8gdGVzdCBwID4gMC4wNS4gVGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcmVzaWR1YWxzIGlzIG5vcm1hbC4KCmBgYHtyfQptID0gYW92KE1lYW4gfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IHJlYWN0aW9udGltZV9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAojIyMgQU5PVkEKCmBgYHtyfQplekFOT1ZBKAogIHJlYWN0aW9udGltZV9wX3N1bW1hcnksCiAgZHYgPSBNZWFuLAogIHdpZCA9IFBhcnRpY2lwYW50LAogIHdpdGhpbiA9IGMoR3VpZGUsIEJsb2NrKQopCmBgYAoKIyMgSW5wdXQgVGltZQpgYGB7cn0KaW5wdXR0aW1lX3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKE1vZGUgPT0gIk5vdmljZSIsIFBoYXNlID09ICJUcmFpbmluZyIgJiBSZXN1bHQgPT0gVFJVRSAmIElzT3V0bGllciA9PSBGQUxTRSkgJT4lCiAgZ3JvdXBfYnkoUGFydGljaXBhbnQsIEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShNZWFuID0gbWVhbihJbnB1dFRpbWUpLCAuZ3JvdXBzPSJkcm9wIikKCiMgYmVjYXVzZSBQNCBoYXMgemVybyBub3ZpY2UgdHJpYWwgaW4gQjMsIHdlIGF2ZXJhZ2VkIHZhbHVlcyBiZXR3ZWVuIHRoYXQgb2YgQjEgYW5kIEIyCm5ld1JvdyA9IGMoIlA0IiwgIlNoZWV0IiwgIlRyYWluaW5nIiwgIkIzIiwgMTEuMjY0Njc4NSkKaW5wdXR0aW1lX3Bfc3VtbWFyeSA9IHJiaW5kKGlucHV0dGltZV9wX3N1bW1hcnksIG5ld1JvdykKIyBiZWNhdXNlIFAxMSBoYXMgemVybyBub3ZpY2UgdHJpYWwgaW4gQjMsIHdlIGF2ZXJhZ2VkIHZhbHVlcyBiZXR3ZWVuIHRoYXQgb2YgQjEgYW5kIEIyCm5ld1JvdyA9IGMoIlAxMSIsICJTaGVldCIsICJUcmFpbmluZyIsICJCMyIsIDcuNzA2KQojIG1lcmdlIG5ldyByb3cgaW50byB0YWJsZQppbnB1dHRpbWVfcF9zdW1tYXJ5ID0gcmJpbmQoaW5wdXR0aW1lX3Bfc3VtbWFyeSwgbmV3Um93KQojIGNvbnZlcnQgZnJvbSBjaGFyYWN0ZXIgdG8gbnVtYmVycwppbnB1dHRpbWVfcF9zdW1tYXJ5JE1lYW4gPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoaW5wdXR0aW1lX3Bfc3VtbWFyeSRNZWFuKSkKaW5wdXR0aW1lX3Bfc3VtbWFyeQoKaW5wdXR0aW1lX29jdG8gPC0gc3Vic2V0KGlucHV0dGltZV9wX3N1bW1hcnksICBHdWlkZSA9PSAiT2N0byIsIE1lYW4sIGRyb3AgPSBUUlVFKQppbnB1dHRpbWVfc2hlZXQgPC0gc3Vic2V0KGlucHV0dGltZV9wX3N1bW1hcnksICBHdWlkZSA9PSAiU2hlZXQiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShpbnB1dHRpbWVfc2hlZXQsIGlucHV0dGltZV9vY3RvKQoKaW5wdXR0aW1lX2IxIDwtIHN1YnNldChpbnB1dHRpbWVfcF9zdW1tYXJ5LCAgQmxvY2sgPT0gIkIxIiwgTWVhbiwgZHJvcCA9IFRSVUUpCmlucHV0dGltZV9iMiA8LSBzdWJzZXQoaW5wdXR0aW1lX3Bfc3VtbWFyeSwgIEJsb2NrID09ICJCMiIsIE1lYW4sIGRyb3AgPSBUUlVFKQppbnB1dHRpbWVfYjMgPC0gc3Vic2V0KGlucHV0dGltZV9wX3N1bW1hcnksICBCbG9jayA9PSAiQjMiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShpbnB1dHRpbWVfYjIsIGlucHV0dGltZV9iMSkKTWVhbkRpZmZDSShpbnB1dHRpbWVfYjMsIGlucHV0dGltZV9iMSkKCmlucHV0dGltZV9zdW1tYXJ5IDwtIGlucHV0dGltZV9wX3N1bW1hcnkgJT4lCiAgZ3JvdXBfYnkoR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKHN1bW1hcnlfd2l0aF9jaShNZWFuKSwgLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShMb3dlclZhbHVlID0gaWZfZWxzZShMb3dlclZhbHVlIDwgMCwgMCwgTG93ZXJWYWx1ZSkpCmlucHV0dGltZV9zdW1tYXJ5CgpgYGAKCiMjIyBHcmFwaAoKYGBge3J9CnBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuNCkKCmdncGxvdChkYXRhPWlucHV0dGltZV9zdW1tYXJ5LCBhZXMoeD1CbG9jaywgeT1NZWFuVmFsdWUsIGdyb3VwPUd1aWRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49TG93ZXJWYWx1ZSwgeW1heD1VcHBlclZhbHVlKSwgd2lkdGg9LjMsIHBvc2l0aW9uPXBkKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1HdWlkZSksIHBvc2l0aW9uPXBkKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1HdWlkZSwgc2hhcGU9R3VpZGUpLCBzaXplPTMsIHBvc2l0aW9uPXBkKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPWZvcm1hdChyb3VuZChNZWFuVmFsdWUsMSksbnNtYWxsPTEpLCBjb2xvcj1HdWlkZSksIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICAgIHNpemU9NCwgbnVkZ2VfeD1pZmVsc2UoaW5wdXR0aW1lX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuMywgMC4zKSwKICAgICAgICAgICAgbnVkZ2VfeT1pZmVsc2UoaW5wdXR0aW1lX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuNCwgMC40KQogICkrCiAgZXhwYW5kX2xpbWl0cyh5PWMoMCwxMS41KSkrCiAgbGFicyh4PSJCbG9jayIsIHk9IlRpbWUgKHMpIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiQjEtVHJhaW4iLCAiQjItVHJhaW4iLCAiQjMtVHJhaW4iKSkrCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNkMzU0MDAiLCAiIzk1YTVhNiIpKSsKICAjIGZhY2V0X2dyaWQoc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIikrCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICAjbGVnZW5kLnBvc2l0aW9uID0gYygwLjgsIDAuMTUpLCBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwKICAgICAgICAjIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMCwgciA9IDUsIGIgPSAwLCBsID0gMCkpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAwLCBiID0gMCwgbCA9IDApKSkKYGBgCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPCAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm90IG5vcm1hbC4KCmBgYHtyfQptID0gYW92KE1lYW4gfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGlucHV0dGltZV9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAoKIyMjIERhdGEgVHJhbnNmb3JtYXRpb24KU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm93IG5vcm1hbC4KCmBgYHtyfQppbnB1dHRpbWVfcF9zdW1tYXJ5JFRyYW5zVmFsID0gc3FydChpbnB1dHRpbWVfcF9zdW1tYXJ5JE1lYW4pCm0gPSBhb3YoVHJhbnNWYWwgfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGlucHV0dGltZV9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAoKIyMjIEFOT1ZBCgpgYGB7cn0KZXpBTk9WQSgKICBpbnB1dHRpbWVfcF9zdW1tYXJ5LAogIGR2ID0gVHJhbnNWYWwsCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KGlucHV0dGltZV9wX3N1bW1hcnkkVHJhbnNWYWwsIAogICAgICAgICAgICAgICAgaW5wdXR0aW1lX3Bfc3VtbWFyeSRCbG9jaywgCiAgICAgICAgICAgICAgICBwYWlyZWQ9VFJVRSwgCiAgICAgICAgICAgICAgICBwLmFkaj0iYm9uZiIpCmBgYAoKCgojIEFDQ1VSQUNZCgojIyBPdmVyYWxsIFRyYWluaW5nCmBgYHtyfQphY2N1cmFjeV9vdmVyYWxsdHJhaW5pbmdfcF9zdW1tYXJ5IDwtIHRyaWFscyAlPiUKICBmaWx0ZXIoUGhhc2UgPT0gIlRyYWluaW5nIiAmICFJc091dGxpZXIpICU+JQogIGdyb3VwX2J5KFBhcnRpY2lwYW50LCBHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoTWVhbiA9IG1lYW4oUmVzdWx0KSwgLmdyb3Vwcz0iZHJvcCIpCmFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19wX3N1bW1hcnkKCm92ZXJhbGx0cmFpbmluZ2FjY19vY3RvIDwtIHN1YnNldChhY2N1cmFjeV9vdmVyYWxsdHJhaW5pbmdfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIk9jdG8iLCBNZWFuLCBkcm9wID0gVFJVRSkKb3ZlcmFsbHRyYWluaW5nYWNjX3NoZWV0IDwtIHN1YnNldChhY2N1cmFjeV9vdmVyYWxsdHJhaW5pbmdfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIlNoZWV0IiwgTWVhbiwgZHJvcCA9IFRSVUUpCk1lYW5EaWZmQ0kob3ZlcmFsbHRyYWluaW5nYWNjX3NoZWV0LCBvdmVyYWxsdHJhaW5pbmdhY2Nfb2N0bykKCmFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19zdW1tYXJ5IDwtIGFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19wX3N1bW1hcnkgJT4lCiAgZ3JvdXBfYnkoR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKHN1bW1hcnlfd2l0aF9jaShNZWFuKSwgLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShMb3dlclZhbHVlID0gaWZfZWxzZShMb3dlclZhbHVlIDwgMCwgMCwgTG93ZXJWYWx1ZSkpCgphY2N1cmFjeV9vdmVyYWxsdHJhaW5pbmdfc3VtbWFyeQpgYGAKCiMjIyBHcmFwaAoKYGBge3J9CnBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuNCkKCmdncGxvdChkYXRhPWFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19zdW1tYXJ5LCBhZXMoeD1CbG9jaywgeT1NZWFuVmFsdWUsIGdyb3VwPUd1aWRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49TG93ZXJWYWx1ZSwgeW1heD1VcHBlclZhbHVlKSwgd2lkdGg9LjMsIHBvc2l0aW9uPXBkKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1HdWlkZSksIHBvc2l0aW9uPXBkKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1HdWlkZSwgc2hhcGU9R3VpZGUpLCBzaXplPTMsIHBvc2l0aW9uPXBkKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXNwcmludGYoIiUuMGYiLCAxMDAqTWVhblZhbHVlKSwgY29sb3I9R3VpZGUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgICBzaXplPTQsIG51ZGdlX3g9aWZlbHNlKGFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjMsIDAuMyksCiAgICAgICAgICAgIG51ZGdlX3k9aWZlbHNlKGFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIDAuMSwgLTAuMSkKICApKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBmdW5jdGlvbih4KSBwYXN0ZTAoeCoxMDApLGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogICMgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX3BlcmNlbnQoKSwgYnJlYWtzID0gc2VxKDAsMSwwLjI1KSkrCiAgZXhwYW5kX2xpbWl0cyh5PWMoMCwxKSkrCiAgbGFicyh4PSJCbG9jayIsIHk9IkFjY3VyYWN5ICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkIxLVRyYWluIiwgIkIyLVRyYWluIiwgIkIzLVRyYWluIikpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjZDM1NDAwIiwgIiM5NWE1YTYiKSxsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX3NoYXBlX2Rpc2NyZXRlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgc2NhbGVfbGluZXR5cGUobGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBmYWNldF9ncmlkKHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZSIpKwogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSsKICB0aGVtZShsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC41LCAwLjEpLCBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMCwgciA9IDUsIGIgPSAwLCBsID0gMCkpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAwLCBiID0gMCwgbCA9IDApKSkKYGBgCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm9ybWFsLgoKYGBge3J9Cm0gPSBhb3YoTWVhbiB+IEJsb2NrKkd1aWRlICsgRXJyb3IoUGFydGljaXBhbnQpLCBkYXRhID0gYWNjdXJhY3lfb3ZlcmFsbHRyYWluaW5nX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgoKIyMjIEFOT1ZBCmBgYHtyfQplekFOT1ZBKAogIGFjY3VyYWN5X292ZXJhbGx0cmFpbmluZ19wX3N1bW1hcnksCiAgZHYgPSBNZWFuLAogIHdpZCA9IFBhcnRpY2lwYW50LAogIHdpdGhpbiA9IGMoR3VpZGUsIEJsb2NrKQopCmBgYAoKIyMgRXhwZXJ0IFRyYWluaW5nCgpgYGB7cn0KYWNjdXJhY3lfcF9leHBlcnRfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKFBoYXNlID09ICJUcmFpbmluZyIgJiBNb2RlID09ICJFeHBlcnQiICYgIUlzT3V0bGllcikgJT4lCiAgZ3JvdXBfYnkoUGFydGljaXBhbnQsIEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShNZWFuID0gbWVhbihSZXN1bHQpLCAuZ3JvdXBzPSJkcm9wIikKYWNjdXJhY3lfcF9leHBlcnRfc3VtbWFyeQoKZXhwZXJ0YWNjX29jdG8gPC0gc3Vic2V0KGFjY3VyYWN5X3BfZXhwZXJ0X3N1bW1hcnksICBHdWlkZSA9PSAiT2N0byIsIE1lYW4sIGRyb3AgPSBUUlVFKQpleHBlcnRhY2Nfc2hlZXQgPC0gc3Vic2V0KGFjY3VyYWN5X3BfZXhwZXJ0X3N1bW1hcnksICBHdWlkZSA9PSAiU2hlZXQiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShleHBlcnRhY2Nfc2hlZXQsIGV4cGVydGFjY19vY3RvKQoKZXhwZXJ0YWNjX2IxIDwtIHN1YnNldChhY2N1cmFjeV9wX2V4cGVydF9zdW1tYXJ5LCAgQmxvY2sgPT0gIkIxIiwgTWVhbiwgZHJvcCA9IFRSVUUpCmV4cGVydGFjY19iMiA8LSBzdWJzZXQoYWNjdXJhY3lfcF9leHBlcnRfc3VtbWFyeSwgIEJsb2NrID09ICJCMiIsIE1lYW4sIGRyb3AgPSBUUlVFKQpleHBlcnRhY2NfYjMgPC0gc3Vic2V0KGFjY3VyYWN5X3BfZXhwZXJ0X3N1bW1hcnksICBCbG9jayA9PSAiQjMiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShleHBlcnRhY2NfYjMsIGV4cGVydGFjY19iMikKCmFjY3VyYWN5X2V4cGVydF9zdW1tYXJ5IDwtIGFjY3VyYWN5X3BfZXhwZXJ0X3N1bW1hcnkgJT4lCiAgZ3JvdXBfYnkoR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKHN1bW1hcnlfd2l0aF9jaShNZWFuKSwgLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShMb3dlclZhbHVlID0gaWZfZWxzZShMb3dlclZhbHVlIDwgMCwgMCwgTG93ZXJWYWx1ZSkpCmFjY3VyYWN5X2V4cGVydF9zdW1tYXJ5CmBgYAoKCiMjIyBHcmFwaAoKYGBge3J9CmdncGxvdChkYXRhPWFjY3VyYWN5X2V4cGVydF9zdW1tYXJ5LCBhZXMoeD1CbG9jaywgeT1NZWFuVmFsdWUsIGdyb3VwPUd1aWRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49TG93ZXJWYWx1ZSwgeW1heD1VcHBlclZhbHVlKSwgd2lkdGg9LjMsIHBvc2l0aW9uPXBkKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1HdWlkZSksIHBvc2l0aW9uPXBkKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1HdWlkZSwgc2hhcGU9R3VpZGUpLCBzaXplPTMsIHBvc2l0aW9uPXBkKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXNwcmludGYoIiUuMGYiLCAxMDAqTWVhblZhbHVlKSwgY29sb3I9R3VpZGUpLCBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgICBzaXplPTQsIG51ZGdlX3g9aWZlbHNlKGFjY3VyYWN5X2V4cGVydF9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjMsIDAuMyksCiAgICAgICAgICAgIG51ZGdlX3k9aWZlbHNlKGFjY3VyYWN5X2V4cGVydF9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIDAuMSwgLTAuMSkKICApKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBmdW5jdGlvbih4KSBwYXN0ZTAoeCoxMDApLGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogICMgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX3BlcmNlbnQoKSwgYnJlYWtzID0gc2VxKDAsMSwwLjI1KSkrCiAgZXhwYW5kX2xpbWl0cyh5PWMoMCwxKSkgKwogIGxhYnMoeD0iQmxvY2siLCB5PSJBY2N1cmFjeSAoJSkiKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJCMS1UcmFpbiIsICJCMi1UcmFpbiIsICJCMy1UcmFpbiIpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IikpKwogIGZhY2V0X2dyaWQoc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIikrCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpKwogIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAsIHIgPSA1LCBiID0gMCwgbCA9IDApKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMCwgYiA9IDAsIGwgPSAwKSkpCmBgYAoKCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm9ybWFsLgoKYGBge3J9Cm0gPSBhb3YoTWVhbiB+IEJsb2NrKkd1aWRlICsgRXJyb3IoUGFydGljaXBhbnQpLCBkYXRhID0gYWNjdXJhY3lfcF9leHBlcnRfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKYGBge3J9CmV6QU5PVkEoCiAgYWNjdXJhY3lfcF9leHBlcnRfc3VtbWFyeSwKICBkdiA9IE1lYW4sCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KGFjY3VyYWN5X3BfZXhwZXJ0X3N1bW1hcnkkTWVhbiwgCiAgICAgICAgICAgICAgICBhY2N1cmFjeV9wX2V4cGVydF9zdW1tYXJ5JEJsb2NrLCAKICAgICAgICAgICAgICAgIHBhaXJlZD1UUlVFLCAKICAgICAgICAgICAgICAgIHAuYWRqPSJib25mIikKYGBgCgojIyBOb3ZpY2UgVHJhaW5pbmcKCmBgYHtyfQphY2N1cmFjeV9wX25vdmljZV9zdW1tYXJ5IDwtIHRyaWFscyAlPiUKICBmaWx0ZXIoUGhhc2UgPT0gIlRyYWluaW5nIiAmIE1vZGUgPT0gIk5vdmljZSIgJiAhSXNPdXRsaWVyKSAlPiUKICBncm91cF9ieShQYXJ0aWNpcGFudCwgR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKE1lYW4gPSBtZWFuKFJlc3VsdCksIC5ncm91cHM9ImRyb3AiKQoKIyBiZWNhdXNlIFAxMSBoYXMgemVybyBub3ZpY2UgdHJpYWwgaW4gQjMsIHdlIGF2ZXJhZ2VkIHZhbHVlcyBiZXR3ZWVuIHRoYXQgb2YgQjEgYW5kIEIyCm5ld1JvdyA9IGMoIlAxMSIsICJTaGVldCIsICJUcmFpbmluZyIsICJCMyIsIDAuNjc4NTcxNDUpCiMgbWVyZ2UgbmV3IHJvdyBpbnRvIHRhYmxlCmFjY3VyYWN5X3Bfbm92aWNlX3N1bW1hcnkgPSByYmluZChhY2N1cmFjeV9wX25vdmljZV9zdW1tYXJ5LCBuZXdSb3cpCiMgY29udmVydCBmcm9tIGNoYXJhY3RlciB0byBudW1iZXJzCmFjY3VyYWN5X3Bfbm92aWNlX3N1bW1hcnkkTWVhbiA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihhY2N1cmFjeV9wX25vdmljZV9zdW1tYXJ5JE1lYW4pKQoKYWNjdXJhY3lfcF9ub3ZpY2Vfc3VtbWFyeQoKbm92aWNlYWNjX29jdG8gPC0gc3Vic2V0KGFjY3VyYWN5X3Bfbm92aWNlX3N1bW1hcnksICBHdWlkZSA9PSAiT2N0byIsIE1lYW4sIGRyb3AgPSBUUlVFKQpub3ZpY2VhY2Nfc2hlZXQgPC0gc3Vic2V0KGFjY3VyYWN5X3Bfbm92aWNlX3N1bW1hcnksICBHdWlkZSA9PSAiU2hlZXQiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShub3ZpY2VhY2Nfc2hlZXQsIG5vdmljZWFjY19vY3RvKQoKYWNjdXJhY3lfbm92aWNlX3N1bW1hcnkgPC0gYWNjdXJhY3lfcF9ub3ZpY2Vfc3VtbWFyeSAlPiUKICBncm91cF9ieShHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoc3VtbWFyeV93aXRoX2NpKE1lYW4pLCAuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKExvd2VyVmFsdWUgPSBpZl9lbHNlKExvd2VyVmFsdWUgPCAwLCAwLCBMb3dlclZhbHVlKSkKYWNjdXJhY3lfbm92aWNlX3N1bW1hcnkKYGBgCgoKIyMjIEdyYXBoCgpgYGB7cn0KcGQgPC0gcG9zaXRpb25fZG9kZ2UoMC40KQoKZ2dwbG90KGRhdGE9YWNjdXJhY3lfbm92aWNlX3N1bW1hcnksIGFlcyh4PUJsb2NrLCB5PU1lYW5WYWx1ZSwgZ3JvdXA9R3VpZGUpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1Mb3dlclZhbHVlLCB5bWF4PVVwcGVyVmFsdWUpLCB3aWR0aD0uMywgcG9zaXRpb249cGQpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPUd1aWRlKSwgcG9zaXRpb249cGQpKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPUd1aWRlLCBzaGFwZT1HdWlkZSksIHNpemU9MywgcG9zaXRpb249cGQpKwogIGdlb21fdGV4dChhZXMobGFiZWw9c3ByaW50ZigiJS4wZiIsIDEwMCpNZWFuVmFsdWUpLCBjb2xvcj1HdWlkZSksIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICAgIHNpemU9NCwgbnVkZ2VfeD1pZmVsc2UoYWNjdXJhY3lfbm92aWNlX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuMywgMC4zKSwKICAgICAgICAgICAgbnVkZ2VfeT1pZmVsc2UoYWNjdXJhY3lfbm92aWNlX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgMC4wNSwgLTAuMDUpCiAgKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gZnVuY3Rpb24oeCkgcGFzdGUwKHgqMTAwKSxicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICAjIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9wZXJjZW50KCksIGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogIGV4cGFuZF9saW1pdHMoeT1jKDAsMSkpKwogIGxhYnMoeD0iQmxvY2siLCB5PSJBY2N1cmFjeSAoJSkiKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJCMS1UcmFpbiIsICJCMi1UcmFpbiIsICJCMy1UcmFpbiIpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IikpKwogIGZhY2V0X2dyaWQoc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIikrCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpKwogIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAsIHIgPSA1LCBiID0gMCwgbCA9IDApKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMCwgYiA9IDAsIGwgPSAwKSkpCmBgYAoKCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm9ybWFsLgoKYGBge3J9Cm0gPSBhb3YoTWVhbiB+IEJsb2NrKkd1aWRlICsgRXJyb3IoUGFydGljaXBhbnQpLCBkYXRhID0gYWNjdXJhY3lfcF9ub3ZpY2Vfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKYGBge3J9CmV6QU5PVkEoCiAgYWNjdXJhY3lfcF9ub3ZpY2Vfc3VtbWFyeSwKICBkdiA9IE1lYW4sCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyBHdWVzcyAoUHJlLVRlc3QpCgpgYGB7cn0KYWNjdXJhY3lfcHJldGVzdF9wX3N1bW1hcnkgPC0gdHJpYWxzICU+JQogIGZpbHRlcihQaGFzZSA9PSAiUHJlVGVzdCIgJiAhSXNPdXRsaWVyKSAlPiUKICBncm91cF9ieShQYXJ0aWNpcGFudCwgR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKE1lYW4gPSBtZWFuKFJlc3VsdCksIC5ncm91cHM9ImRyb3AiKQphY2N1cmFjeV9wcmV0ZXN0X3Bfc3VtbWFyeQoKYWNjdXJhY3lfcHJldGVzdF9zdW1tYXJ5IDwtIGFjY3VyYWN5X3ByZXRlc3RfcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koTWVhbiksIC5ncm91cHM9ImRyb3AiKSAlPiUKICBtdXRhdGUoTG93ZXJWYWx1ZSA9IGlmX2Vsc2UoTG93ZXJWYWx1ZSA8IDAsIDAsIExvd2VyVmFsdWUpKQoKcHJldGVzdGFjY19vY3RvIDwtIHN1YnNldChhY2N1cmFjeV9wcmV0ZXN0X3Bfc3VtbWFyeSwgIEd1aWRlID09ICJPY3RvIiwgTWVhbiwgZHJvcCA9IFRSVUUpCnByZXRlc3RhY2Nfc2hlZXQgPC0gc3Vic2V0KGFjY3VyYWN5X3ByZXRlc3RfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIlNoZWV0IiwgTWVhbiwgZHJvcCA9IFRSVUUpCk1lYW5EaWZmQ0kocHJldGVzdGFjY19zaGVldCwgcHJldGVzdGFjY19vY3RvKQoKYWNjdXJhY3lfcHJldGVzdF9zdW1tYXJ5CmBgYAojIyMgR3JhcGgKCmBgYHtyfQpnZ3Bsb3QoZGF0YT1hY2N1cmFjeV9wcmV0ZXN0X3N1bW1hcnksIGFlcyh4PUd1aWRlLCB5PU1lYW5WYWx1ZSwgZmlsbCA9IEd1aWRlKSkgKwogIGdlb21fYmFyKHNpemU9MyxzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49TG93ZXJWYWx1ZSwgeW1heD1VcHBlclZhbHVlKSwgd2lkdGg9LjMsIHBvc2l0aW9uPXBkKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zcHJpbnRmKCIlLjBmIiwgMTAwKk1lYW5WYWx1ZSksIGNvbG9yPUd1aWRlKSwKICAgICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRSwKICAgICAgICAgICAgc2l6ZT00LCBudWRnZV95ID0gMC4xCiAgKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gZnVuY3Rpb24oeCkgcGFzdGUwKHgqMTAwKSxicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICAjIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9wZXJjZW50KCksIGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogIGV4cGFuZF9saW1pdHMoeT1jKDAsMSkpKwogIGxhYnMoeD0iR3VpZGUiLCB5PSJBY2N1cmFjeSAoJSkiKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IiksbGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IiksbGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX2xpbmV0eXBlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gJ2dyZXknKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAsIHIgPSA1LCBiID0gMCwgbCA9IDApKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMCwgYiA9IDAsIGwgPSAwKSkpCmBgYAoKCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm9ybWFsLgoKYGBge3J9Cm0gPSBhb3YoTWVhbiB+IEd1aWRlICsgRXJyb3IoUGFydGljaXBhbnQpLCBkYXRhID0gYWNjdXJhY3lfcHJldGVzdF9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAoKIyMjIEFOT1ZBCgpgYGB7cn0KZXpBTk9WQSgKICBhY2N1cmFjeV9wcmV0ZXN0X3Bfc3VtbWFyeSwKICBkdiA9IE1lYW4sCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSkKKQpgYGAKCiMjIFJlY2FsbCAoVGVzdCkKCmBgYHtyfQphY2N1cmFjeV90ZXN0X3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKFBoYXNlID09ICJUZXN0IiAmICFJc091dGxpZXIpICU+JQogIGdyb3VwX2J5KFBhcnRpY2lwYW50LCBHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoTWVhbiA9IG1lYW4oUmVzdWx0KSwgLmdyb3Vwcz0iZHJvcCIpCmFjY3VyYWN5X3Rlc3RfcF9zdW1tYXJ5CgptYWludGVzdF9vY3RvIDwtIHN1YnNldChhY2N1cmFjeV90ZXN0X3Bfc3VtbWFyeSwgIEd1aWRlID09ICJPY3RvIiwgTWVhbiwgZHJvcCA9IFRSVUUpCm1haW50ZXN0X3NoZWV0IDwtIHN1YnNldChhY2N1cmFjeV90ZXN0X3Bfc3VtbWFyeSwgIEd1aWRlID09ICJTaGVldCIsIE1lYW4sIGRyb3AgPSBUUlVFKQpNZWFuRGlmZkNJKG1haW50ZXN0X3NoZWV0LCBtYWludGVzdF9vY3RvKQoKYWNjdXJhY3lfdGVzdF9zdW1tYXJ5IDwtIGFjY3VyYWN5X3Rlc3RfcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koTWVhbiksIC5ncm91cHM9ImRyb3AiKSAlPiUKICBtdXRhdGUoTG93ZXJWYWx1ZSA9IGlmX2Vsc2UoTG93ZXJWYWx1ZSA8IDAsIDAsIExvd2VyVmFsdWUpKQoKYWNjdGVzdF9iMSA8LSBzdWJzZXQoYWNjdXJhY3lfdGVzdF9wX3N1bW1hcnksICBCbG9jayA9PSAiQjEiLCBNZWFuLCBkcm9wID0gVFJVRSkKYWNjdGVzdF9iMiA8LSBzdWJzZXQoYWNjdXJhY3lfdGVzdF9wX3N1bW1hcnksICBCbG9jayA9PSAiQjIiLCBNZWFuLCBkcm9wID0gVFJVRSkKYWNjdGVzdF9iMyA8LSBzdWJzZXQoYWNjdXJhY3lfdGVzdF9wX3N1bW1hcnksICBCbG9jayA9PSAiQjMiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShhY2N0ZXN0X2IyLCBhY2N0ZXN0X2IxKQpNZWFuRGlmZkNJKGFjY3Rlc3RfYjMsIGFjY3Rlc3RfYjIpCgphY2N1cmFjeV90ZXN0X3N1bW1hcnkKYGBgCgoKIyMjIEdyYXBoCgpgYGB7cn0KcGQgPC0gcG9zaXRpb25fZG9kZ2UoMC40KQoKZ2dwbG90KGRhdGE9YWNjdXJhY3lfdGVzdF9zdW1tYXJ5LCBhZXMoeD1CbG9jaywgeT1NZWFuVmFsdWUsIGdyb3VwPUd1aWRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49TG93ZXJWYWx1ZSwgeW1heD1VcHBlclZhbHVlKSwgd2lkdGg9LjMsIHBvc2l0aW9uPXBkKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1HdWlkZSksIHBvc2l0aW9uPXBkKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1HdWlkZSwgc2hhcGU9R3VpZGUpLCBzaXplPTMsIHBvc2l0aW9uPXBkKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXNwcmludGYoIiUuMGYiLCAxMDAqTWVhblZhbHVlKSwgY29sb3I9R3VpZGUpLAogICAgICAgICAgICBzaXplPTQsIG51ZGdlX3g9aWZlbHNlKGFjY3VyYWN5X3Rlc3Rfc3VtbWFyeSRHdWlkZT09Ik9jdG8iLCAtMC40LCAwLjQpLAogICAgICAgICAgICBudWRnZV95PWlmZWxzZShhY2N1cmFjeV90ZXN0X3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgMC4xLCAtMC4xKQogICkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhc3RlMCh4KjEwMCksYnJlYWtzID0gc2VxKDAsMSwwLjI1KSkrCiAgIyBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfcGVyY2VudCgpLCBicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICBleHBhbmRfbGltaXRzKHk9YygwLDEpKSsKICBsYWJzKHg9IkJsb2NrIiwgeT0iQWNjdXJhY3kgKCUpIikrCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiQjEtVGVzdCIsICJCMi1UZXN0IiwgIkIzLVRlc3QiKSkrCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNkMzU0MDAiLCAiIzk1YTVhNiIpLGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgc2NhbGVfc2hhcGVfZGlzY3JldGUobGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBzY2FsZV9saW5ldHlwZShsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIGZhY2V0X2dyaWQoc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIikrCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpKwogIHRoZW1lKGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjUsIDAuMSksIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsCiAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICdncmV5JyksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSAwLCByID0gNSwgYiA9IDAsIGwgPSAwKSksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDAsIGIgPSAwLCBsID0gMCkpKQpgYGAKCgoKIyMjIEFzc3VtcHRpb25zClNoYXBpcm8gdGVzdCBwID4gMC4wNS4gVGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcmVzaWR1YWxzIGlzIG5vcm1hbC4KCmBgYHtyfQptID0gYW92KE1lYW4gfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGFjY3VyYWN5X3Rlc3RfcF9zdW1tYXJ5KQpzaGFwaXJvLnRlc3QocmVzaWR1YWxzKG0kV2l0aGluKSkKcGxvdE5vcm1hbEhpc3RvZ3JhbShyZXNpZHVhbHMobSRXaXRoaW4pKQpxcW5vcm0ocmVzaWR1YWxzKG0kV2l0aGluKSk7IHFxbGluZShyZXNpZHVhbHMobSRXaXRoaW4pKQpgYGAKCiMjIyBBTk9WQQpgYGB7cn0KZXpBTk9WQSgKICBhY2N1cmFjeV90ZXN0X3Bfc3VtbWFyeSwKICBkdiA9IE1lYW4sCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KGFjY3VyYWN5X3Rlc3RfcF9zdW1tYXJ5JE1lYW4sIAogICAgICAgICAgICAgICAgYWNjdXJhY3lfdGVzdF9wX3N1bW1hcnkkQmxvY2ssIAogICAgICAgICAgICAgICAgcGFpcmVkPVRSVUUsIAogICAgICAgICAgICAgICAgcC5hZGo9ImJvbmYiKQpgYGAKCiMjIEluY2lkZW50YWwgTGVhcm5pbmcgKFBvc3QtdGVzdCkKCmBgYHtyfQojIGV4Y2x1ZGluZyB0YXJnZXRzCmFjY3VyYWN5X3Bvc3R0ZXN0X3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKFBoYXNlID09ICJQb3N0VGVzdCIgJiAhSXNPdXRsaWVyKSAlPiUKICBmaWx0ZXIoVHJpYWxOYW1lICE9ICJBYnUgRGhhYmkiICYgVHJpYWxOYW1lICE9ICJBbXN0ZXJkYW0iICYgVHJpYWxOYW1lICE9ICJEdWJhaSIgJiBUcmlhbE5hbWUgIT0gIkxvcyBBbmdlbGVzIiAmIFRyaWFsTmFtZSAhPSAiTWFkcmlkIiAmIFRyaWFsTmFtZSAhPSAiUGFyaXMiICYgVHJpYWxOYW1lICE9ICJTaW5nYXBvcmUiICYgVHJpYWxOYW1lICE9ICJUb2t5byIgJiBUcmlhbE5hbWUgIT0gIkF1c3RpbiIgJiBUcmlhbE5hbWUgIT0gIkRvaGEiICYgVHJpYWxOYW1lICE9ICJGcmFua2Z1cnQiICYgVHJpYWxOYW1lICE9ICJIb3VzdG9uIiAmIFRyaWFsTmFtZSAhPSAiTWlsYW4iICYgVHJpYWxOYW1lICE9ICJQcmFndWUiICYgVHJpYWxOYW1lICE9ICJTZW91bCIgJiBUcmlhbE5hbWUgIT0gIlRvcm9udG8iKSAlPiUKICBncm91cF9ieShQYXJ0aWNpcGFudCwgR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKE1lYW4gPSBtZWFuKFJlc3VsdCksIC5ncm91cHM9ImRyb3AiKQphY2N1cmFjeV9wb3N0dGVzdF9wX3N1bW1hcnkKCmFjY3VyYWN5cG9zdHRlc3Rfb2N0byA8LSBzdWJzZXQoYWNjdXJhY3lfcG9zdHRlc3RfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIk9jdG8iLCBNZWFuLCBkcm9wID0gVFJVRSkKYWNjdXJhY3lwb3N0dGVzdF9zaGVldCA8LSBzdWJzZXQoYWNjdXJhY3lfcG9zdHRlc3RfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIlNoZWV0IiwgTWVhbiwgZHJvcCA9IFRSVUUpCk1lYW5EaWZmQ0koYWNjdXJhY3lwb3N0dGVzdF9vY3RvLCBhY2N1cmFjeXBvc3R0ZXN0X3NoZWV0KQoKYWNjdXJhY3lfcG9zdHRlc3Rfc3VtbWFyeSA8LSBhY2N1cmFjeV9wb3N0dGVzdF9wX3N1bW1hcnkgJT4lCiAgZ3JvdXBfYnkoR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKHN1bW1hcnlfd2l0aF9jaShNZWFuKSwgLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShMb3dlclZhbHVlID0gaWZfZWxzZShMb3dlclZhbHVlIDwgMCwgMCwgTG93ZXJWYWx1ZSkpCmFjY3VyYWN5X3Bvc3R0ZXN0X3N1bW1hcnkKYGBgCgojIyMgR3JhcGgKCmBgYHtyfQpnZ3Bsb3QoZGF0YT1hY2N1cmFjeV9wb3N0dGVzdF9zdW1tYXJ5LCBhZXMoeD1HdWlkZSwgeT1NZWFuVmFsdWUsIGZpbGwgPSBHdWlkZSkpICsKICBnZW9tX2JhcihzaXplPTMsc3RhdD0iaWRlbnRpdHkiKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUxvd2VyVmFsdWUsIHltYXg9VXBwZXJWYWx1ZSksIHdpZHRoPS4zLCBwb3NpdGlvbj1wZCkgKwogIGdlb21fdGV4dChhZXMobGFiZWw9c3ByaW50ZigiJS4wZiIsIDEwMCpNZWFuVmFsdWUpLCBjb2xvcj1HdWlkZSksCiAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICAgIHNpemU9NCwgbnVkZ2VfeSA9IDAuMDUsIG51ZGdlX3ggPSAwLjMKICApKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBmdW5jdGlvbih4KSBwYXN0ZTAoeCoxMDApLGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogICMgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX3BlcmNlbnQoKSwgYnJlYWtzID0gc2VxKDAsMSwwLjI1KSkrCiAgZXhwYW5kX2xpbWl0cyh5PWMoMCwxKSkrCiAgbGFicyh4PSJHdWlkZSIsIHk9IkFjY3VyYWN5ICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjZDM1NDAwIiwgIiM5NWE1YTYiKSxsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjZDM1NDAwIiwgIiM5NWE1YTYiKSxsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX3NoYXBlX2Rpc2NyZXRlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgc2NhbGVfbGluZXR5cGUobGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAxMikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMCwgciA9IDUsIGIgPSAwLCBsID0gMCkpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAwLCBiID0gMCwgbCA9IDApKSkKYGBgCgoKCiMjIyBBc3N1bXB0aW9ucwpTaGFwaXJvIHRlc3QgcCA+IDAuMDUuIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHJlc2lkdWFscyBpcyBub3JtYWwuCgpgYGB7cn0KbSA9IGFvdihNZWFuIH4gR3VpZGUgKyBFcnJvcihQYXJ0aWNpcGFudCksIGRhdGEgPSBhY2N1cmFjeV9wb3N0dGVzdF9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAoKIyMjIEFOT1ZBCgpgYGB7cn0KZXpBTk9WQSgKICBhY2N1cmFjeV9wb3N0dGVzdF9wX3N1bW1hcnksCiAgZHYgPSBNZWFuLAogIHdpZCA9IFBhcnRpY2lwYW50LAogIHdpdGhpbiA9IGMoR3VpZGUpCikKYGBgCgojIyBMZWFybmluZyBDdXJ2ZSAoY29tYmluZWQsIG9ubHkgOCB0cmFpbmVkIGdlc3R1cmVzKQoKYGBge3J9CnRhcmdldHMgPC0gYygiQWJ1IERoYWJpIiwgIkFtc3RlcmRhbSIsICJEdWJhaSIsICJMb3MgQW5nZWxlcyIsICJNYWRyaWQiLCAiUGFyaXMiLCAiU2luZ2Fwb3JlIiwgIlRva3lvIiwgIkF1c3RpbiIsICJEb2hhIiwgIkZyYW5rZnVydCIsICJIb3VzdG9uIiwgIk1pbGFuIiwgIlByYWd1ZSIsICJTZW91bCIsICJUb3JvbnRvIikKCmN1cnZlX3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKFRyaWFsTmFtZSAlaW4lIHRhcmdldHMgJiBQaGFzZSE9IlRyYWluaW5nIiAmICFJc091dGxpZXIpICU+JQogIG11dGF0ZShQaGFzZU5hbWUgPSBpZmVsc2UoUGhhc2U9PSJUZXN0IiAmIEJsb2NrPT0iQjEiLCAiVGVzdCBCMSIsCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFBoYXNlPT0iVGVzdCIgJiBCbG9jaz09IkIyIiwgIlRlc3QgQjIiLAogICAgICAgICAgICAgICAgICAgIGlmZWxzZShQaGFzZT09IlRlc3QiICYgQmxvY2s9PSJCMyIsICJUZXN0IEIzIiwKICAgICAgICAgICAgICAgICAgICBpZmVsc2UoUGhhc2U9PSJQcmVUZXN0IiwgIlByZVRlc3QiLAogICAgICAgICAgICAgICAgICAgIGlmZWxzZShQaGFzZT09IlBvc3RUZXN0IiwgIlBvc3RUZXN0IixOQSkpKSkpKSAlPiUKICBtdXRhdGUoUGhhc2VOYW1lID0gZmN0X3JlbGV2ZWwoUGhhc2VOYW1lLCAKICAgICAgICAgICAgIlByZVRlc3QiLCAiVGVzdCBCMSIsICJUZXN0IEIyIiwgIlRlc3QgQjMiLCAiUG9zdFRlc3QiKSkgJT4lCiAgbXV0YXRlKFBoYXNlTmFtZSA9IGFzLmZhY3RvcihQaGFzZU5hbWUpKSAlPiUKICBncm91cF9ieShQYXJ0aWNpcGFudCwgR3VpZGUsIFBoYXNlTmFtZSkgJT4lCiAgc3VtbWFyaXplKE1lYW4gPSBtZWFuKFJlc3VsdCksIC5ncm91cHM9ImRyb3AiKQpjdXJ2ZV9wX3N1bW1hcnkKCmN1cnZlX3N1bW1hcnkgPC0gY3VydmVfcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZU5hbWUpICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koTWVhbiksIC5ncm91cHM9ImRyb3AiKSAlPiUKICBtdXRhdGUoTG93ZXJWYWx1ZSA9IGlmX2Vsc2UoTG93ZXJWYWx1ZSA8IDAsIDAsIExvd2VyVmFsdWUpKQpjdXJ2ZV9zdW1tYXJ5CgoKY3VydmVfdGVzdEIzIDwtIHN1YnNldChjdXJ2ZV9wX3N1bW1hcnksICBQaGFzZU5hbWUgPT0gIlRlc3QgQjMiLCBNZWFuLCBkcm9wID0gVFJVRSkKY3VydmVfcG9zdHRlc3QgPC0gc3Vic2V0KGN1cnZlX3Bfc3VtbWFyeSwgIFBoYXNlTmFtZSA9PSAiUG9zdFRlc3QiLCBNZWFuLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShjdXJ2ZV9wb3N0dGVzdCwgY3VydmVfdGVzdEIzKQpgYGAKCiMjIyBHcmFwaAoKYGBge3J9CnBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuNCkKCmdncGxvdChkYXRhPWN1cnZlX3N1bW1hcnksIGFlcyh4PVBoYXNlTmFtZSwgeT1NZWFuVmFsdWUsIGdyb3VwPUd1aWRlKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49TG93ZXJWYWx1ZSwgeW1heD1VcHBlclZhbHVlKSwgd2lkdGg9LjMsIHBvc2l0aW9uPXBkKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1HdWlkZSksIHBvc2l0aW9uPXBkKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1HdWlkZSwgc2hhcGU9R3VpZGUpLCBzaXplPTMsIHBvc2l0aW9uPXBkKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXNwcmludGYoIiUuMGYiLCAxMDAqTWVhblZhbHVlKSwgY29sb3I9R3VpZGUpLAogICAgICAgICAgICBzaXplPTQsIG51ZGdlX3g9aWZlbHNlKGN1cnZlX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuMywgMC4zKSwKICAgICAgICAgICAgbnVkZ2VfeT1pZmVsc2UoY3VydmVfc3VtbWFyeSRHdWlkZT09Ik9jdG8iLCAwLjEsIC0wLjEpLAogICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFCiAgKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gZnVuY3Rpb24oeCkgcGFzdGUwKHgqMTAwKSxicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICAjIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9wZXJjZW50KCksIGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogIGV4cGFuZF9saW1pdHMoeT1jKDAsMSkpKwogIGxhYnMoeD0iUGhhc2UiLCB5PSJBY2N1cmFjeSAoJSkiKSsKICAjIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkIxLVRlc3QiLCAiQjItVGVzdCIsICJCMy1UZXN0IikpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjZDM1NDAwIiwgIiM5NWE1YTYiKSxsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX3NoYXBlX2Rpc2NyZXRlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgc2NhbGVfbGluZXR5cGUobGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBmYWNldF9ncmlkKHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZSIpKwogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSsKICB0aGVtZShsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC41LCAwLjEpLCBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMCwgciA9IDUsIGIgPSAwLCBsID0gMCkpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAwLCBiID0gMCwgbCA9IDApKSkKYGBgCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm9ybWFsLgoKYGBge3J9Cm0gPSBhb3YoTWVhbiB+IFBoYXNlTmFtZSpHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGN1cnZlX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKYGBge3J9CiMgY3VydmVfcF9zdW1tYXJ5X25ldyA9IGZpbHRlcihjdXJ2ZV9wX3N1bW1hcnksIFBoYXNlTmFtZT09IlRlc3QgQjMiIHwgUGhhc2VOYW1lPT0iUG9zdFRlc3QiKQojIGN1cnZlX3Bfc3VtbWFyeV9uZXcKCmV6QU5PVkEoCiAgY3VydmVfcF9zdW1tYXJ5LAogIGR2ID0gTWVhbiwKICB3aWQgPSBQYXJ0aWNpcGFudCwKICB3aXRoaW4gPSBjKEd1aWRlLCBQaGFzZU5hbWUpCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KGN1cnZlX3Bfc3VtbWFyeSRNZWFuLCAKICAgICAgICAgICAgICAgIGN1cnZlX3Bfc3VtbWFyeSRQaGFzZU5hbWUsIAogICAgICAgICAgICAgICAgcGFpcmVkPVRSVUUsIAogICAgICAgICAgICAgICAgcC5hZGo9ImJvbmYiKQpgYGAKCiMgT1RIRVJTCgojIyBFeHBlcnQgTW9kZSBSYXRlIChkdXJpbmcgVHJhaW5pbmcpCmBgYHtyfQpleHBlcnRwcm9wb3J0aW9uX3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKFBoYXNlID09ICJUcmFpbmluZyIgJiAhSXNPdXRsaWVyKSAlPiUKICBncm91cF9ieShQYXJ0aWNpcGFudCwgR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKEV4cGVydENvdW50ID0gc3VtKE1vZGU9PSJFeHBlcnQiKSwgCiAgICAgICAgICAgIFRvdGFsID0gc3VtKE1vZGU9PSJOb3ZpY2UiKSArIHN1bShNb2RlPT0iRXhwZXJ0IiksCiAgICAgICAgICAgIEV4cGVydFBlcmNlbnQgPSAoc3VtKE1vZGU9PSJFeHBlcnQiKS9Ub3RhbCksCiAgICAgICAgICAgIC5ncm91cHM9ImRyb3AiKQpleHBlcnRwcm9wb3J0aW9uX3Bfc3VtbWFyeQoKZXhwZXJ0cHJvX29jdG8gPC0gc3Vic2V0KGV4cGVydHByb3BvcnRpb25fcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIk9jdG8iLCBFeHBlcnRQZXJjZW50LCBkcm9wID0gVFJVRSkKZXhwZXJ0cHJvX3NoZWV0IDwtIHN1YnNldChleHBlcnRwcm9wb3J0aW9uX3Bfc3VtbWFyeSwgIEd1aWRlID09ICJTaGVldCIsIEV4cGVydFBlcmNlbnQsIGRyb3AgPSBUUlVFKQpNZWFuRGlmZkNJKGV4cGVydHByb19zaGVldCwgZXhwZXJ0cHJvX29jdG8pCgpleHBlcnRwcm9fYjEgPC0gc3Vic2V0KGV4cGVydHByb3BvcnRpb25fcF9zdW1tYXJ5LCAgQmxvY2sgPT0gIkIxIiwgRXhwZXJ0UGVyY2VudCwgZHJvcCA9IFRSVUUpCmV4cGVydHByb19iMiA8LSBzdWJzZXQoZXhwZXJ0cHJvcG9ydGlvbl9wX3N1bW1hcnksICBCbG9jayA9PSAiQjIiLCBFeHBlcnRQZXJjZW50LCBkcm9wID0gVFJVRSkKZXhwZXJ0cHJvX2IzIDwtIHN1YnNldChleHBlcnRwcm9wb3J0aW9uX3Bfc3VtbWFyeSwgIEJsb2NrID09ICJCMyIsIEV4cGVydFBlcmNlbnQsIGRyb3AgPSBUUlVFKQpNZWFuRGlmZkNJKGV4cGVydHByb19iMiwgZXhwZXJ0cHJvX2IxKQpNZWFuRGlmZkNJKGV4cGVydHByb19iMywgZXhwZXJ0cHJvX2IxKQoKZXhwZXJ0cHJvcG9ydGlvbl9zdW1tYXJ5IDwtIGV4cGVydHByb3BvcnRpb25fcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koRXhwZXJ0UGVyY2VudCksIC5ncm91cHM9ImRyb3AiKSAlPiUKICBtdXRhdGUoTG93ZXJWYWx1ZSA9IGlmX2Vsc2UoTG93ZXJWYWx1ZSA8IDAsIDAsIExvd2VyVmFsdWUpKQpleHBlcnRwcm9wb3J0aW9uX3N1bW1hcnkKYGBgCgojIyMgR3JhcGgKCmBgYHtyfQpwZCA8LSBwb3NpdGlvbl9kb2RnZSgwLjQpCgpnZ3Bsb3QoZGF0YT1leHBlcnRwcm9wb3J0aW9uX3N1bW1hcnksIGFlcyh4PUJsb2NrLCB5PU1lYW5WYWx1ZSwgZ3JvdXA9R3VpZGUpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1Mb3dlclZhbHVlLCB5bWF4PVVwcGVyVmFsdWUpLCB3aWR0aD0uMywgcG9zaXRpb249cGQpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPUd1aWRlKSwgcG9zaXRpb249cGQpKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPUd1aWRlLCBzaGFwZT1HdWlkZSksIHNpemU9MywgcG9zaXRpb249cGQpKwogIGdlb21fdGV4dChhZXMobGFiZWw9c3ByaW50ZigiJS4wZiIsIDEwMCpNZWFuVmFsdWUpLCBjb2xvcj1HdWlkZSksCiAgICAgICAgICAgIHNpemU9NCwgbnVkZ2VfeD1pZmVsc2UoZXhwZXJ0cHJvcG9ydGlvbl9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjM1LCAwLjM1KSwKICAgICAgICAgICAgbnVkZ2VfeT1pZmVsc2UoZXhwZXJ0cHJvcG9ydGlvbl9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjE1LCAwLjE1KQogICkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhc3RlMCh4KjEwMCksYnJlYWtzID0gc2VxKDAsMSwwLjI1KSkrCiAgIyBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfcGVyY2VudCgpLCBicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICBleHBhbmRfbGltaXRzKHk9YygwLDEpKSsKICBsYWJzKHg9IkJsb2NrIiwgeT0iVXNhZ2UgUmF0ZSAoJSkiKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJCMS1UcmFpbiIsICJCMi1UcmFpbiIsICJCMy1UcmFpbiIpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IiksbGFiZWxzPWMoIk9DVE9QT0NVUyIsIkNSSUJTSEVFVCIpKSsKICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShsYWJlbHM9YygiT0NUT1BPQ1VTIiwiQ1JJQlNIRUVUIikpKwogIHNjYWxlX2xpbmV0eXBlKGxhYmVscz1jKCJPQ1RPUE9DVVMiLCJDUklCU0hFRVQiKSkrCiAgZmFjZXRfZ3JpZChzY2FsZXMgPSAiZnJlZSIsIHNwYWNlID0gImZyZWUiKSsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAxMikrCiAgdGhlbWUobGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNSwgMC4xKSwgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gJ2dyZXknKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAsIHIgPSA1LCBiID0gMCwgbCA9IDApKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMCwgYiA9IDAsIGwgPSAwKSkpCmBgYAoKIyMjIEFzc3VtcHRpb25zClNoYXBpcm8gdGVzdCBwID4gMC4wNS4gVGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcmVzaWR1YWxzIGlzIG5vcm1hbC4KCmBgYHtyfQptID0gYW92KEV4cGVydFBlcmNlbnQgfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGV4cGVydHByb3BvcnRpb25fcF9zdW1tYXJ5KQpzaGFwaXJvLnRlc3QocmVzaWR1YWxzKG0kV2l0aGluKSkKcGxvdE5vcm1hbEhpc3RvZ3JhbShyZXNpZHVhbHMobSRXaXRoaW4pKQpxcW5vcm0ocmVzaWR1YWxzKG0kV2l0aGluKSk7IHFxbGluZShyZXNpZHVhbHMobSRXaXRoaW4pKQpgYGAKCiMjIyBBTk9WQQpgYGB7cn0KZXpBTk9WQSgKICBleHBlcnRwcm9wb3J0aW9uX3Bfc3VtbWFyeSwKICBkdiA9IEV4cGVydFBlcmNlbnQsCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KGV4cGVydHByb3BvcnRpb25fcF9zdW1tYXJ5JEV4cGVydFBlcmNlbnQsIAogICAgICAgICAgICAgICAgZXhwZXJ0cHJvcG9ydGlvbl9wX3N1bW1hcnkkQmxvY2ssIAogICAgICAgICAgICAgICAgcGFpcmVkPVRSVUUsIAogICAgICAgICAgICAgICAgcC5hZGo9ImJvbmYiKQpgYGAKCiMjIEV4cGxvcmF0aW9uIE1vZGUgUmF0ZSAoZHVyaW5nIFRyYWluaW5nKQoKYGBge3J9CmV4cGxvcmVwcm9wX3Bfc3VtbWFyeSA8LSB0cmlhbHMgJT4lCiAgZmlsdGVyKFBoYXNlID09ICJUcmFpbmluZyIgJiAhSXNPdXRsaWVyKSAlPiUKICBtdXRhdGUoaXNFeHBsb3JpbmcgPSBpZmVsc2UoR3JpcER1cmF0aW9uPjAsIDEsIDApKSAlPiUKICBncm91cF9ieShQYXJ0aWNpcGFudCwgR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKEZyZXF1ZW5jeSA9IHN1bShpc0V4cGxvcmluZyksCiAgICAgICAgICAgIFRvdGFsID0gc3VtKE1vZGU9PSJOb3ZpY2UiKSArIHN1bShNb2RlPT0iRXhwZXJ0IiksCiAgICAgICAgICAgIFByb3BvcnRpb24gPSAoRnJlcXVlbmN5L1RvdGFsKSwKICAgICAgICAgICAgLmdyb3Vwcz0iZHJvcCIpCmV4cGxvcmVwcm9wX3Bfc3VtbWFyeQoKZXhwbG9yZXByb3Bfc3VtbWFyeSA8LSBleHBsb3JlcHJvcF9wX3N1bW1hcnkgJT4lCiAgZ3JvdXBfYnkoR3VpZGUsIFBoYXNlLCBCbG9jaykgJT4lCiAgc3VtbWFyaXplKHN1bW1hcnlfd2l0aF9jaShQcm9wb3J0aW9uKSwgLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShMb3dlclZhbHVlID0gaWZfZWxzZShMb3dlclZhbHVlIDwgMCwgMCwgTG93ZXJWYWx1ZSkpCmV4cGxvcmVwcm9wX3N1bW1hcnkKCmV4cGxvcmVwcm9fb2N0byA8LSBzdWJzZXQoZXhwbG9yZXByb3BfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIk9jdG8iLCBQcm9wb3J0aW9uLCBkcm9wID0gVFJVRSkKZXhwbG9yZXByb19zaGVldCA8LSBzdWJzZXQoZXhwbG9yZXByb3BfcF9zdW1tYXJ5LCAgR3VpZGUgPT0gIlNoZWV0IiwgUHJvcG9ydGlvbiwgZHJvcCA9IFRSVUUpCk1lYW5EaWZmQ0koZXhwbG9yZXByb19zaGVldCwgZXhwbG9yZXByb19vY3RvKQoKZXhwbG9yZXByb19iMSA8LSBzdWJzZXQoZXhwbG9yZXByb3BfcF9zdW1tYXJ5LCAgQmxvY2sgPT0gIkIxIiwgUHJvcG9ydGlvbiwgZHJvcCA9IFRSVUUpCmV4cGxvcmVwcm9fYjIgPC0gc3Vic2V0KGV4cGxvcmVwcm9wX3Bfc3VtbWFyeSwgIEJsb2NrID09ICJCMiIsIFByb3BvcnRpb24sIGRyb3AgPSBUUlVFKQpleHBsb3JlcHJvX2IzIDwtIHN1YnNldChleHBsb3JlcHJvcF9wX3N1bW1hcnksICBCbG9jayA9PSAiQjMiLCBQcm9wb3J0aW9uLCBkcm9wID0gVFJVRSkKTWVhbkRpZmZDSShleHBsb3JlcHJvX2IyLCBleHBsb3JlcHJvX2IxKQpNZWFuRGlmZkNJKGV4cGxvcmVwcm9fYjMsIGV4cGxvcmVwcm9fYjIpCmBgYAoKIyMjIEdyYXBoCgpgYGB7cn0KcGQgPC0gcG9zaXRpb25fZG9kZ2UoMC40KQoKZ2dwbG90KGRhdGE9ZXhwbG9yZXByb3Bfc3VtbWFyeSwgYWVzKHg9QmxvY2ssIHk9TWVhblZhbHVlLCBncm91cD1HdWlkZSkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUxvd2VyVmFsdWUsIHltYXg9VXBwZXJWYWx1ZSksIHdpZHRoPS4zLCBwb3NpdGlvbj1wZCkgKwogIGdlb21fbGluZShhZXMoY29sb3I9R3VpZGUpLCBwb3NpdGlvbj1wZCkrCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9R3VpZGUsIHNoYXBlPUd1aWRlKSwgc2l6ZT0zLCBwb3NpdGlvbj1wZCkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zcHJpbnRmKCIlLjBmIiwgMTAwKk1lYW5WYWx1ZSksIGNvbG9yPUd1aWRlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSwKICAgICAgICAgICAgc2l6ZT00LCBudWRnZV94PWlmZWxzZShleHBsb3JlcHJvcF9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjMsIDAuMyksCiAgICAgICAgICAgIG51ZGdlX3k9aWZlbHNlKGV4cGxvcmVwcm9wX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuMDUsIDAuMDUpCiAgKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gZnVuY3Rpb24oeCkgcGFzdGUwKHgqMTAwKSxicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICAjIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9wZXJjZW50KCksIGJyZWFrcyA9IHNlcSgwLDEsMC4yNSkpKwogIGV4cGFuZF9saW1pdHMoeT1jKDAsMSkpKwogIGxhYnMoeD0iQmxvY2siLCB5PSJVc2FnZSBSYXRlICglKSIpKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkIxLVRyYWluIiwgIkIyLVRyYWluIiwgIkIzLVRyYWluIikpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjZDM1NDAwIiwgIiM5NWE1YTYiKSkrCiAgZmFjZXRfZ3JpZChzY2FsZXMgPSAiZnJlZSIsIHNwYWNlID0gImZyZWUiKSsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAxMikrCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICdncmV5JyksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMCwgciA9IDUsIGIgPSAwLCBsID0gMCkpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSAwLCBiID0gMCwgbCA9IDApKSkKYGBgCgojIyMgQXNzdW1wdGlvbnMKU2hhcGlybyB0ZXN0IHAgPCAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm90IG5vcm1hbC4KCmBgYHtyfQptID0gYW92KFByb3BvcnRpb24gfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGV4cGxvcmVwcm9wX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgRGF0YSBUcmFuc2Zvcm1hdGlvbgpTaGFwaXJvIHRlc3QgcCA+IDAuMDUuIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHJlc2lkdWFscyBpcyBub3cgbm9ybWFsLgoKYGBge3J9CmV4cGxvcmVwcm9wX3Bfc3VtbWFyeSRUcmFuc1ZhbCA9IHNxcnQoZXhwbG9yZXByb3BfcF9zdW1tYXJ5JFByb3BvcnRpb24pCm0gPSBhb3YoVHJhbnNWYWwgfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IGV4cGxvcmVwcm9wX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKYGBge3J9CmV6QU5PVkEoCiAgZXhwbG9yZXByb3BfcF9zdW1tYXJ5LAogIGR2ID0gVHJhbnNWYWwsCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KGV4cGxvcmVwcm9wX3Bfc3VtbWFyeSRUcmFuc1ZhbCwgCiAgICAgICAgICAgICAgICBleHBsb3JlcHJvcF9wX3N1bW1hcnkkQmxvY2ssIAogICAgICAgICAgICAgICAgcGFpcmVkPVRSVUUsIAogICAgICAgICAgICAgICAgcC5hZGo9ImJvbmYiKQpgYGAKCiMjIE9DVE8gRXhwbG9yYXRpb24gTW9kZSBSYXRlIChkdXJpbmcgVHJhaW5pbmcpCgpgYGB7cn0KZXhwbG9yZXByb3Bfb2N0b19wX3N1bW1hcnkgPC0gdHJpYWxzICU+JQogIGZpbHRlcihHdWlkZSA9PSAiT2N0byIgJiBQaGFzZSA9PSAiVHJhaW5pbmciICYgIUlzT3V0bGllcikgJT4lCiAgbXV0YXRlKGlzRXhwbG9yaW5nID0gaWZlbHNlKEdyaXBEdXJhdGlvbj4wLCAxLCAwKSkgJT4lCiAgZ3JvdXBfYnkoUGFydGljaXBhbnQsIEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShGcmVxdWVuY3kgPSBzdW0oaXNFeHBsb3JpbmcpLAogICAgICAgICAgICBUb3RhbCA9IHN1bShNb2RlPT0iTm92aWNlIikgKyBzdW0oTW9kZT09IkV4cGVydCIpLAogICAgICAgICAgICBQcm9wb3J0aW9uID0gKEZyZXF1ZW5jeS9Ub3RhbCksCiAgICAgICAgICAgIC5ncm91cHM9ImRyb3AiKQpleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeQoKZXhwbG9yZXByb3Bfb2N0b19zdW1tYXJ5IDwtIGV4cGxvcmVwcm9wX29jdG9fcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLEJsb2NrKSAlPiUKICBzdW1tYXJpemUoc3VtbWFyeV93aXRoX2NpKFByb3BvcnRpb24pLCAuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKExvd2VyVmFsdWUgPSBpZl9lbHNlKExvd2VyVmFsdWUgPCAwLCAwLCBMb3dlclZhbHVlKSkKZXhwbG9yZXByb3Bfb2N0b19zdW1tYXJ5CgpleHBsb3JlcHJvX29jdG9fYjEgPC0gc3Vic2V0KGV4cGxvcmVwcm9wX29jdG9fcF9zdW1tYXJ5LCAgQmxvY2sgPT0gIkIxIiwgUHJvcG9ydGlvbiwgZHJvcCA9IFRSVUUpCmV4cGxvcmVwcm9fb2N0b19iMiA8LSBzdWJzZXQoZXhwbG9yZXByb3Bfb2N0b19wX3N1bW1hcnksICBCbG9jayA9PSAiQjIiLCBQcm9wb3J0aW9uLCBkcm9wID0gVFJVRSkKZXhwbG9yZXByb19vY3RvX2IzIDwtIHN1YnNldChleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeSwgIEJsb2NrID09ICJCMyIsIFByb3BvcnRpb24sIGRyb3AgPSBUUlVFKQpNZWFuRGlmZkNJKGV4cGxvcmVwcm9fb2N0b19iMiwgZXhwbG9yZXByb19vY3RvX2IxKQpNZWFuRGlmZkNJKGV4cGxvcmVwcm9fb2N0b19iMywgZXhwbG9yZXByb19vY3RvX2IxKQpgYGAKCiMjIyBHcmFwaAoKYGBge3J9CnBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuNCkKCmdncGxvdChkYXRhPWV4cGxvcmVwcm9wX29jdG9fc3VtbWFyeSwgYWVzKHg9QmxvY2ssIHk9TWVhblZhbHVlLCBncm91cD1HdWlkZSkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUxvd2VyVmFsdWUsIHltYXg9VXBwZXJWYWx1ZSksIHdpZHRoPS4zLCBwb3NpdGlvbj1wZCkgKwogIGdlb21fbGluZShhZXMoY29sb3I9R3VpZGUpLCBwb3NpdGlvbj1wZCkrCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9R3VpZGUsIHNoYXBlPUd1aWRlKSwgc2l6ZT0zLCBwb3NpdGlvbj1wZCkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zcHJpbnRmKCIlLjBmIiwgMTAwKk1lYW5WYWx1ZSksIGNvbG9yPUd1aWRlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSwKICAgICAgICAgICAgc2l6ZT00LCBudWRnZV94PWlmZWxzZShleHBsb3JlcHJvcF9vY3RvX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuMywgMC4zKSwKICAgICAgICAgICAgbnVkZ2VfeT1pZmVsc2UoZXhwbG9yZXByb3Bfb2N0b19zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjA1LCAwLjA1KQogICkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGZ1bmN0aW9uKHgpIHBhc3RlMCh4KjEwMCksYnJlYWtzID0gc2VxKDAsMSwwLjI1KSkrCiAgIyBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfcGVyY2VudCgpLCBicmVha3MgPSBzZXEoMCwxLDAuMjUpKSsKICBleHBhbmRfbGltaXRzKHk9YygwLDEpKSsKICBsYWJzKHg9IkJsb2NrIiwgeT0iVXNhZ2UgUmF0ZSAoJSkiKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJCMS1UcmFpbiIsICJCMi1UcmFpbiIsICJCMy1UcmFpbiIpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI2QzNTQwMCIsICIjOTVhNWE2IikpKwogIGZhY2V0X2dyaWQoc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIikrCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTIpKwogIHRoZW1lKHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAnZ3JleScpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDAsIHIgPSA1LCBiID0gMCwgbCA9IDApKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gMCwgYiA9IDAsIGwgPSAwKSkpCmBgYAoKIyMjIEFzc3VtcHRpb25zClNoYXBpcm8gdGVzdCBwIDwgMC4wNS4gVGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgcmVzaWR1YWxzIGlzIG5vdCBub3JtYWwuCgpgYGB7cn0KbSA9IGFvdihQcm9wb3J0aW9uIH4gQmxvY2sgKyBFcnJvcihQYXJ0aWNpcGFudCksIGRhdGEgPSBleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgRGF0YSBUcmFuc2Zvcm1hdGlvbgpTaGFwaXJvIHRlc3QgcCA+IDAuMDUuIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHJlc2lkdWFscyBpcyBub3cgbm9ybWFsLgoKYGBge3J9CmV4cGxvcmVwcm9wX29jdG9fcF9zdW1tYXJ5JFRyYW5zVmFsID0gc3FydChleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeSRQcm9wb3J0aW9uKQptID0gYW92KFRyYW5zVmFsIH4gQmxvY2sgKyBFcnJvcihQYXJ0aWNpcGFudCksIGRhdGEgPSBleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKYGBge3J9CmV6QU5PVkEoCiAgZXhwbG9yZXByb3Bfb2N0b19wX3N1bW1hcnksCiAgZHYgPSBUcmFuc1ZhbCwKICB3aWQgPSBQYXJ0aWNpcGFudCwKICB3aXRoaW4gPSBjKEJsb2NrKQopCmBgYAoKIyMjIFBhaXJ3aXNlIENvbXBhcmlzb24KYGBge3J9CnBhaXJ3aXNlLnQudGVzdChleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeSRUcmFuc1ZhbCwgCiAgICAgICAgICAgICAgICBleHBsb3JlcHJvcF9vY3RvX3Bfc3VtbWFyeSRCbG9jaywgCiAgICAgICAgICAgICAgICBwYWlyZWQ9VFJVRSwgCiAgICAgICAgICAgICAgICBwLmFkaj0iYm9uZiIpCmBgYAoKIyMgRXhwbG9yZSBEdXJhdGlvbgoKYGBge3J9Cm1vZGVkdGltZV9wX3N1bW1hcnkgPC0gdHJpYWxzICU+JQogIGZpbHRlcihNb2RlID09ICJOb3ZpY2UiLCBQaGFzZSA9PSAiVHJhaW5pbmciICYgUmVzdWx0ID09IFRSVUUgJiBJc091dGxpZXIgPT0gRkFMU0UpICU+JQogIGdyb3VwX2J5KFBhcnRpY2lwYW50LCBHdWlkZSwgUGhhc2UsIEJsb2NrKSAlPiUKICBzdW1tYXJpemUoTWVhbklkbGUgPSBtZWFuKElkbGVEdXJhdGlvbiksIE1lYW5HcmlwID0gbWVhbihHcmlwRHVyYXRpb24pLCBNZWFuVHJpZ2dlciA9IG1lYW4oVHJpZ2dlckR1cmF0aW9uKSwgLmdyb3Vwcz0iZHJvcCIpCgojIGJlY2F1c2UgUDQgaGFzIHplcm8gbm92aWNlIHRyaWFsIGluIEIzLCB3ZSBhdmVyYWdlZCB2YWx1ZXMgYmV0d2VlbiB0aGF0IG9mIEIxIGFuZCBCMgpuZXdSb3cgPSBjKCJQNCIsICJTaGVldCIsICJUcmFpbmluZyIsICJCMyIsIDIuNTEwOTQ2NSwgNy43MjI4MjE0NSwgMS45NjgyNjgpCm1vZGVkdGltZV9wX3N1bW1hcnkgPSByYmluZChtb2RlZHRpbWVfcF9zdW1tYXJ5LCBuZXdSb3cpCiMgYmVjYXVzZSBQMTEgaGFzIHplcm8gbm92aWNlIHRyaWFsIGluIEIzLCB3ZSBhdmVyYWdlZCB2YWx1ZXMgYmV0d2VlbiB0aGF0IG9mIEIxIGFuZCBCMgpuZXdSb3cgPSBjKCJQMTEiLCAiU2hlZXQiLCAiVHJhaW5pbmciLCAiQjMiLCAzLjM5MTMzMzUsIDQuMDYzNSwgMS43MzQ3NSkKIyBtZXJnZSBuZXcgcm93IGludG8gdGFibGUKbW9kZWR0aW1lX3Bfc3VtbWFyeSA9IHJiaW5kKG1vZGVkdGltZV9wX3N1bW1hcnksIG5ld1JvdykKIyAjIGNvbnZlcnQgZnJvbSBjaGFyYWN0ZXIgdG8gbnVtYmVycwptb2RlZHRpbWVfcF9zdW1tYXJ5JE1lYW5JZGxlIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1vZGVkdGltZV9wX3N1bW1hcnkkTWVhbklkbGUpKQptb2RlZHRpbWVfcF9zdW1tYXJ5JE1lYW5HcmlwIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1vZGVkdGltZV9wX3N1bW1hcnkkTWVhbkdyaXApKQptb2RlZHRpbWVfcF9zdW1tYXJ5JE1lYW5UcmlnZ2VyIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1vZGVkdGltZV9wX3N1bW1hcnkkTWVhblRyaWdnZXIpKQoKbW9kZWR0aW1lX3Bfc3VtbWFyeQoKaWRsZXRpbWVfc3VtbWFyeSA8LSBtb2RlZHRpbWVfcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koTWVhbklkbGUpLCAuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKExvd2VyVmFsdWUgPSBpZl9lbHNlKExvd2VyVmFsdWUgPCAwLCAwLCBMb3dlclZhbHVlKSkKaWRsZXRpbWVfc3VtbWFyeQoKZ3JpcHRpbWVfc3VtbWFyeSA8LSBtb2RlZHRpbWVfcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koTWVhbkdyaXApLCAuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKExvd2VyVmFsdWUgPSBpZl9lbHNlKExvd2VyVmFsdWUgPCAwLCAwLCBMb3dlclZhbHVlKSkKZ3JpcHRpbWVfc3VtbWFyeQoKdHJpZ2dlcnRpbWVfc3VtbWFyeSA8LSBtb2RlZHRpbWVfcF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KEd1aWRlLCBQaGFzZSwgQmxvY2spICU+JQogIHN1bW1hcml6ZShzdW1tYXJ5X3dpdGhfY2koTWVhblRyaWdnZXIpLCAuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKExvd2VyVmFsdWUgPSBpZl9lbHNlKExvd2VyVmFsdWUgPCAwLCAwLCBMb3dlclZhbHVlKSkKdHJpZ2dlcnRpbWVfc3VtbWFyeQpgYGAKCiMjIyBHcmFwaAoKYGBge3J9CnBkIDwtIHBvc2l0aW9uX2RvZGdlKDAuNCkKCmdncGxvdChkYXRhPWdyaXB0aW1lX3N1bW1hcnksIGFlcyh4PUJsb2NrLCB5PU1lYW5WYWx1ZSwgZ3JvdXA9R3VpZGUpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1Mb3dlclZhbHVlLCB5bWF4PVVwcGVyVmFsdWUpLCB3aWR0aD0uMywgcG9zaXRpb249cGQpICsKICBnZW9tX2xpbmUoYWVzKGxpbmV0eXBlPUd1aWRlLCBjb2xvcj1HdWlkZSksIHBvc2l0aW9uPXBkKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1HdWlkZSwgc2hhcGU9R3VpZGUpLCBzaXplPTMsIHBvc2l0aW9uPXBkKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPWZvcm1hdChyb3VuZChNZWFuVmFsdWUsMyksbnNtYWxsPTMpLCBjb2xvcj1HdWlkZSksCiAgICAgICAgICAgIHNpemU9NCwgbnVkZ2VfeD1pZmVsc2UoZ3JpcHRpbWVfc3VtbWFyeSRHdWlkZT09Ik9jdG8iLCAtMC4zNSwgMC4zNSksCiAgICAgICAgICAgIG51ZGdlX3k9aWZlbHNlKGdyaXB0aW1lX3N1bW1hcnkkR3VpZGU9PSJPY3RvIiwgLTAuNCwgMC40KQogICkrCiAgZXhwYW5kX2xpbWl0cyh5PWMoMCw2KSkrCiAgbGFicyh4PSJCbG9jayIsIHk9IkV4cGxvcmUgRHVyYXRpb24gKHMpIikrCiAgZmFjZXRfZ3JpZCh+UGhhc2UsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZSIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICAjbGVnZW5kLnBvc2l0aW9uID0gYygwLjg1LCAwLjg1KSwgbGVnZW5kLmRpcmVjdGlvbiA9ICJ2ZXJ0aWNhbCIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSAwLCByID0gNSwgYiA9IDAsIGwgPSAwKSksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDAsIGIgPSAwLCBsID0gMCkpKQpgYGAKCiMjIyBBc3N1bXB0aW9ucwpTaGFwaXJvIHRlc3QgcCA8IDAuMDUuIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHJlc2lkdWFscyBpcyBub3Qgbm9ybWFsLgoKYGBge3J9Cm0gPSBhb3YoTWVhbkdyaXAgfiBCbG9jaypHdWlkZSArIEVycm9yKFBhcnRpY2lwYW50KSwgZGF0YSA9IG1vZGVkdGltZV9wX3N1bW1hcnkpCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobSRXaXRoaW4pKQpwbG90Tm9ybWFsSGlzdG9ncmFtKHJlc2lkdWFscyhtJFdpdGhpbikpCnFxbm9ybShyZXNpZHVhbHMobSRXaXRoaW4pKTsgcXFsaW5lKHJlc2lkdWFscyhtJFdpdGhpbikpCmBgYAoKIyMjIERhdGEgVHJhbnNmb3JtYXRpb24KU2hhcGlybyB0ZXN0IHAgPiAwLjA1LiBUaGUgZGlzdHJpYnV0aW9uIG9mIHRoZSByZXNpZHVhbHMgaXMgbm93IG5vcm1hbC4KCmBgYHtyfQptb2RlZHRpbWVfcF9zdW1tYXJ5JFRyYW5zVmFsID0gc3FydChtb2RlZHRpbWVfcF9zdW1tYXJ5JE1lYW5HcmlwKQptID0gYW92KFRyYW5zVmFsIH4gQmxvY2sqR3VpZGUgKyBFcnJvcihQYXJ0aWNpcGFudCksIGRhdGEgPSBtb2RlZHRpbWVfcF9zdW1tYXJ5KQpzaGFwaXJvLnRlc3QocmVzaWR1YWxzKG0kV2l0aGluKSkKcGxvdE5vcm1hbEhpc3RvZ3JhbShyZXNpZHVhbHMobSRXaXRoaW4pKQpxcW5vcm0ocmVzaWR1YWxzKG0kV2l0aGluKSk7IHFxbGluZShyZXNpZHVhbHMobSRXaXRoaW4pKQpgYGAKIyMjIEFOT1ZBCgpgYGB7cn0KZXpBTk9WQSgKICBtb2RlZHRpbWVfcF9zdW1tYXJ5LAogIGR2ID0gc3FydChNZWFuR3JpcCksCiAgd2lkID0gUGFydGljaXBhbnQsCiAgd2l0aGluID0gYyhHdWlkZSwgQmxvY2spCikKYGBgCgojIyMgUGFpcndpc2UgQ29tcGFyaXNvbgpgYGB7cn0KcGFpcndpc2UudC50ZXN0KHNxcnQobW9kZWR0aW1lX3Bfc3VtbWFyeSRNZWFuR3JpcCksIAogICAgICAgICAgICAgICAgbW9kZWR0aW1lX3Bfc3VtbWFyeSRCbG9jaywgCiAgICAgICAgICAgICAgICBwYWlyZWQ9VFJVRSwgCiAgICAgICAgICAgICAgICBwLmFkaj0iYm9uZiIpCmBgYAoKIyMgRHJhdyBEdXJhdGlvbgoKIyMjIEdyYXBoCgpgYGB7cn0KcGQgPC0gcG9zaXRpb25fZG9kZ2UoMC40KQoKZ2dwbG90KGRhdGE9dHJpZ2dlcnRpbWVfc3VtbWFyeSwgYWVzKHg9QmxvY2ssIHk9TWVhblZhbHVlLCBncm91cD1HdWlkZSkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUxvd2VyVmFsdWUsIHltYXg9VXBwZXJWYWx1ZSksIHdpZHRoPS4zLCBwb3NpdGlvbj1wZCkgKwogIGdlb21fbGluZShhZXMobGluZXR5cGU9R3VpZGUsIGNvbG9yPUd1aWRlKSwgcG9zaXRpb249cGQpKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPUd1aWRlLCBzaGFwZT1HdWlkZSksIHNpemU9MywgcG9zaXRpb249cGQpKwogIGdlb21fdGV4dChhZXMobGFiZWw9Zm9ybWF0KHJvdW5kKE1lYW5WYWx1ZSwzKSxuc21hbGw9MyksIGNvbG9yPUd1aWRlKSwKICAgICAgICAgICAgc2l6ZT00LCBudWRnZV94PWlmZWxzZSh0cmlnZ2VydGltZV9zdW1tYXJ5JEd1aWRlPT0iT2N0byIsIC0wLjM1LCAwLjM1KSwKICAgICAgICAgICAgbnVkZ2VfeT1pZmVsc2UodHJpZ2dlcnRpbWVfc3VtbWFyeSRHdWlkZT09Ik9jdG8iLCAtMC40LCAwLjQpCiAgKSsKICBleHBhbmRfbGltaXRzKHk9YygwLDYpKSsKICBsYWJzKHg9IkJsb2NrIiwgeT0iRHJhdyBEdXJhdGlvbiAocykiKSsKICBmYWNldF9ncmlkKH5QaGFzZSwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjg1LCAwLjE1KSwgbGVnZW5kLmRpcmVjdGlvbiA9ICJ2ZXJ0aWNhbCIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQobWFyZ2luID0gbWFyZ2luKHQgPSAwLCByID0gNSwgYiA9IDAsIGwgPSAwKSksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDAsIGIgPSAwLCBsID0gMCkpKQpgYGAKCiMjIyBBc3N1bXB0aW9ucwpTaGFwaXJvIHRlc3QgcCA+IDAuMDUuIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHJlc2lkdWFscyBpcyBub3JtYWwuCgpgYGB7cn0KbSA9IGFvdihNZWFuVHJpZ2dlciB+IEJsb2NrKkd1aWRlICsgRXJyb3IoUGFydGljaXBhbnQpLCBkYXRhID0gbW9kZWR0aW1lX3Bfc3VtbWFyeSkKc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtJFdpdGhpbikpCnBsb3ROb3JtYWxIaXN0b2dyYW0ocmVzaWR1YWxzKG0kV2l0aGluKSkKcXFub3JtKHJlc2lkdWFscyhtJFdpdGhpbikpOyBxcWxpbmUocmVzaWR1YWxzKG0kV2l0aGluKSkKYGBgCgojIyMgQU5PVkEKCmBgYHtyfQplekFOT1ZBKAogIG1vZGVkdGltZV9wX3N1bW1hcnksCiAgZHYgPSBNZWFuVHJpZ2dlciwKICB3aWQgPSBQYXJ0aWNpcGFudCwKICB3aXRoaW4gPSBjKEd1aWRlLCBCbG9jaykKKQpgYGAKCiMgU1VCSkVDVElWRSBSQVRJTkcKCmBgYHtyfQpyYXRpbmdQYXJ0aWNpcGFudCA8LSByZWFkX2NzdigiLi9kYXRhMi5jc3YiKQpyYXRpbmdDb3VudCA8LSByZWFkX2NzdigiLi9kYXRhMy5jc3YiKQpvdmVyYWxsIDwtIHJlYWRfY3N2KCIuL2RhdGE0LmNzdiIpCmxlbmd0aCh1bmlxdWUob3ZlcmFsbCRQYXJ0aWNpcGFudCkpCnJhdGluZ1BhcnRpY2lwYW50CgpuYW1lcyhyYXRpbmdDb3VudClbM10gPC0gIlN0cm9uZ2x5XG5EaXNhZ3JlZSIKbmFtZXMocmF0aW5nQ291bnQpWzVdIDwtICJTbGlnaHRseVxuRGlzYWdyZWUiCm5hbWVzKHJhdGluZ0NvdW50KVs3XSA8LSAiU2xpZ2h0bHlcbkFncmVlIgpuYW1lcyhyYXRpbmdDb3VudClbOV0gPC0gIlN0cm9uZ2x5XG5BZ3JlZSIKcmF0aW5nQ291bnQKCmxpa2VydChRdWVzdGlvbiB+IC58IEd1aWRlLCBkYXRhPXJhdGluZ0NvdW50LCBsYXlvdXQ9YygxLDIpLAogICAgICAgc2NhbGVzPWxpc3QoeT1saXN0KHJlbGF0aW9uPSJmcmVlIikpLGJldHdlZW49bGlzdCh5PTIuNSksCiAgICAgICBzdHJpcC5sZWZ0PUZBTFNFLCBzdHJpcD1GQUxTRSwKICAgICAgIHBhci5zdHJpcC50ZXh0PWxpc3QoY2V4PTEsIGxpbmVzPTIpLCB5bGFiPU5VTEwsIGNleD0xLjIsCiAgICAgICB4bGltPWMoLTEwMCwtNTAsIC0yNSwgMCwgMjUsIDUwLCA3NSwgMTAwKSwKICAgICAgIFJlZmVyZW5jZVplcm89NCwgYXMucGVyY2VudD0ibm9SaWdodEF4aXMiLAogICAgICAgcmVmZXJlbmNlLmxpbmUuY29sPSJibGFjayIsCiAgICAgICBjb2w9YygiI0QzMTgxOSIsICIjRkY3OTJFIiwgIiNGRkFFNzMiLCAiI0RFRDlEOSIsICIjNzRBRUQ1IiwgIiMzODgxQjgiLCAiIzBFNTI5RiIpLAogICAgICAgYm9yZGVycyA9IGxpc3QoKSwKICAgICAgIHBvc2l0aXZlLm9yZGVyPUZBTFNFLAogICAgICAgbWFpbiA9IGxpc3QoIiIpLAogICAgICAgeGxhYj0iUHJvcG9ydGlvbiAoJSkiLAogICAgICAgYXV0by5rZXk9bGlzdChzcGFjZT0iYm90dG9tIiwgcm93cz0xLCByZXZlcnNlPUZBTFNFLCBwYWRkaW5nLnRleHQ9MSwKICAgICAgICAgICAgICAgICAgICAgcmVjdD0gbGlzdChjb2w9YygiI0QzMTgxOSIsICIjRkY3OTJFIiwgIiNGRkFFNzMiLCAiI0RFRDlEOSIsICIjNzRBRUQ1IiwgIiMzODgxQjgiLCAiIzBFNTI5RiIpLCAjIDwtIFNwZWNpZnkgY29sb3JzIGFnYWluIChmb3Iga2V5cykKICAgICAgICAgICAgICAgICAgICBib3JkZXIgPSAiYmxhY2siKSkpCgojIGV4cG9ydCB0byBwZGY6IDQuMCB4IDguNSBpbmNoCmBgYAoKYGBge3J9CnJhdGluZ1BhcnRpY2lwYW50TG9uZyA9IHBpdm90X2xvbmdlcihyYXRpbmdQYXJ0aWNpcGFudCwgY29scyA9IDU6OSwgbmFtZXNfdG8gPSAiUXVlc3Rpb24iLCB2YWx1ZXNfdG8gPSAiUmF0aW5nIikKcmF0aW5nUGFydGljaXBhbnRMb25nCgp3aWxjb3ggPC0gcmF0aW5nUGFydGljaXBhbnRMb25nICU+JQogIGdyb3VwX2J5KFF1ZXN0aW9uKSAlPiUKICB3aWxjb3hfdGVzdChSYXRpbmcgfiBHdWlkZSwgcGFpcmVkPVRSVUUpICU+JQogIGFkZF9zaWduaWZpY2FuY2UoInAiKQp3aWxjb3gKYGBgCgo=